爬虫技术初探

# -*— coding:utf-8 -*-
# @time   :2021/11/5 17:01
# @Author :zhangzhoubin
'''
1、爬虫:又称网页蜘蛛,是将网页数据按照需要进行抽取,存储到本地数据库中,用于我们构建模型进行数据分析,获取数据中所需的价值。
2、web与http协议的工作流程:
客户端浏览器---url---远程服务器  (超文本传输协议http,客户端通过超文本传输协议对于远程服务器进行请求,服务器端对于请求进行响应)
3、爬虫的流程
(1)确定需求;(2)寻求需求;(3)发送请求;(4)解析数据;(5)存储数据
4、请求方式
get:get是http默认的请求该方式,直接通过链接进行访问,链接中直接附带 相关的参数;缺点:参数直接暴露在链接中,不安全;
post:post方法主要向web提交表单数据,涉及向服务器提交表单的过程,一般采购post请求;优势:相比get请求安全,参数信息不再链接中。
5、Requests
request是Python代码请求的工具。
'''

'''
功能:利用requests进行访问链接,获取所需的信息。
'''
# import requests
# #requests请求网站
# url='https://www.baidu.com/'
# res=requests.get(url=url)  #发起get请求
# print(res)  #获取相应的结果
# print(res.content)  #获取相应的内容(b'.....':二进制的文本流)
# print(res.content.decode('utf-8'))   #将二进制文本流转换成utf-5
# print(res.url)  #请求的链接
# print(res.text)   #响应的内容
# print(res.headers)  #响应头信息
# print(res.request.headers)  #响应头信息()
# print(res.status_code)  #响应的状态码

'''
功能:发送请求,主要解决远程服务器拒绝爬虫工具访问,
'''
# import requests
# # url='https://www.lmonkey.com/'
# url='https://www.jd.com/?cu=true&utm_source=baidu-pinzhuan&utm_medium=cpc&utm_campaign=t_288551095_baidupinzhuan&utm_term=0f3d30c8dba7459bb52f2eb5eba8ac7d_0_f05509cc4e6744568d6ff57a3919bfbc'
#
# '''res=requests.get(url=url) 访问远程服务器是以python访问的(爬虫工具访问),如果远程服务器允许访问则返回的是200,如果拒绝访问则返回其他,
# 并且访问不到任何内容。
# 基于以上存在的问题,主要的原因是'User-Agent': 'python-requests/2.26.0'导致的,有些网页限制爬虫,就需要采用浏览器的方式访问,
# 格式如:user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
# '''
# #拒绝访问的解决方法
# # headers={
# # 'User-Agent':'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
# #              ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
# # }
# # res=requests.get(url=url,headers=headers)
#
# res=requests.get(url=url)
# print(res.request.headers)
# #获取响应状态码
# sta_coda=res.status_code
# print(sta_coda)
# if sta_coda==200:
#     with open('./test.html','w',encoding='utf-8') as fp:
#         fp.write(res.text)

# '''
# 功能:post发送请求,requeests 请求头的定义,可以避免网页对于爬虫的限制,通过伪装为浏览器的方式顺利访问。
# '''
# import requests
# #定义请求URL
# url='https://fanyi.baidu.com/?aldtype=16047#auto/zh'
# #定义头文件
# headers={
# 'User-Agent':'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
#               ' AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#
# }
# #post发送数据
# data={'k':'您好'}
# #发送请求
# res=requests.post(url=url,headers=headers,data=data)
# #接收返回数据
# print(res.status_code)
# print(res.content)

'''
coookie:http请求是无状态请求,不会记住用户的状态和信息,也不清楚用户之前访问过什么,但是网站需要记住用户是否登记时,就需要在用户登录后
创建一些信息,并且 要把这些信息记录在当前的用户的浏览器中记录的内容就是cookie,用户继续使用当前网站时,浏览器就会主动携带这个网站设置的cookie信息
cookie会在浏览器中记录信息,并且在访问时携带这个信息。浏览器更换或者删除cookie信息将丢失,cookie在浏览器中记录信息是不安全,因为不能记录敏感信息。

session:是在服务器端进行数据的记录,并且在给每个用户会生成一个sessionID,并且把这个sessionID设置在和用户的浏览器中,也就是设置为cookie
'''
'''
功能:使用cookie记录的信息进行网页访问
'''
# import requests
#
# url='https://www.imooc.com/'
# #定义头文件
# headers={
# 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36''AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36',
# }
# res=requests.get(url=url,headers=headers)
# if res.status_code==200:
#     print("请求成功")
#     with open('./train.html','w',encoding='utf-8') as fp:
#         fp.write(res.text)
#         print("响应成功")

'''
XPath是XML路径语言,主要用于在XML文档中查找信息的语言,最初主要用于搜寻XML文档中,同时也适用于HTML文档中搜索资源,因此可以
用于爬虫时对于信息的抽取。
XPath常用规则:
nodename:选取此节点的所有子节点;
/ :选取当前节点的直接子节点;
// :选取当前节点的子孙节点;
. :选取当前节点;
.. :选取当前节点的父节点;
@ :选取属性
'''
'''
功能:XPath基本使用
'''
# from lxml import etree
# text='''
# <!DOCTYPE html>
# <html lang='zh-CN'>
# <head>
#     <meta charset="UTF-8">
#     <title>学习猿地-成就自我</title>
# <head>
# <body>
#     <ul>
#         <li><a href="/a/b/c/java/">java工程师</a></li>
#         <li><a href="/a/b/c/python/">python工程师</a></li>
#         <li><a href="/a/b/c/ai/">AI工程师</a></li>
#     </ul>
# </body>
# </html>
# '''
# #使用etree解析html字符串
# html=etree.HTML(text)
# print(html)
# #提取数据
# r=html.xpath('/html/body/ul/li/a/text()')
# print(r) #['java工程师', 'python工程师', 'AI工程师']
# #获取xpath中多个子节点中一个子节点的信息
# r1=html.xpath('/html/body/ul/li[2]/a/text()')
# print(r1)  #['python工程师']

'''
功能:xpath的使用方式
'''
from lxml import etree

#第一种解析的方法
# with open('./test1.html','r',encoding='utf-8') as rf:
#     content=rf.read()
#     html1=etree.HTML(content)
#     res1=html1.xpath('/html/body/ul/li/a/text()')
#     print(res1)

# # #第二种解析的方法
# res2=etree.parse('./test1.html',etree.HTMLParser())
# res=res2.xpath('/html/body/ul/li/a/text()')
# print(res)

# #获取指定标签下的数据
# res2=etree.parse('./test1.html',etree.HTMLParser())
# # res=res2.xpath('//ul[@class="student"]/li/a[@re="/a/b/c/python/"]/text()')
# # print(res)
# #获取属性的名字
# res=res2.xpath('//ul[@class="student"]/li[1]/a/@re')
# print(res)

'''
功能:Xpath实战,实现 网站登录
'''
'''
自动登录网站的流程:
1)get请求login页面,设置cookie,获取_token
2)post请求,提交登录数据,进行登录,并且设置cookie
3)get请求,账户中心,获取默认的订单号
'''
# import requests
# from lxml import etree
#
# class LMonKey():
#     loginurl='https://www.lmonkey.com/login'
#     orderurl='https://www.lmonkey.com/my/order'
#     headers={
#        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#     }
#     #请求对象
#     req=None
#     _token=''
#     order_code=0
#     #请求初始化
#     def __init__(self):
#         self.req=requests.sessions()
#         if self.getlogin():
#             if self.postlogin():
#                 self.getorder()
#
#     #get登录页面,获取_token
#     def getlogin(self):
#         #get请求login,设置cookie,获取_token
#         res=self.req.get(url=self.loginurl,headers=self.headers)
#         if res.status_code==200:
#             print('get请求成功')
#             html=etree.HTML(res.text)
#             self.token=html.xpath('//input[@name="_token"]/@value')[0]
#             print(self.token)
#             print("token获取成功")
#             return True
#         else:
#             print("请求错误")
#
#     #post请求登录,设置cookie
#     def postlogin(self):
#         uname=input("手机号")
#         passw=input("密码")
#         data={
#             '_token':self.token,
#             'username':uname,
#             'password':passw
#         }
#         #发送post请求
#         res=self.req.post(url=self.loginurl,headers=self.headers,data=data)
#         if res.status_code==200 or res.status_code==302:
#             print("登录成功")
#             return True
#     #get请求账户中心,获取边订单号
#     def  getorder(self):
#         pass
#         res=self.req.get(url=self.orderurl,headers=self.headers)
#         if res.status_code==200:
#             print("账户中心请求成功,正在解析数据")
#             html=etree.HTML(res.text)
#             r=html.xpath('//div[@class="avatar-content"//small/text()]')
#             self.order_code=r
#             print(r)
#             return True
#
#
# obj=LMonKey()
'''
xpath实战,爬取文章
'''
# #导入所需库
# import requests,json
# from lxml import etree
#
#
# def  data_get():
#     #请求链接
#     url='https://www.lmonkey.com/t'
#     headers={
#         'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#     }
#     #发送请求
#     res=requests.get(url=url,headers=headers)
#     if res.status_code==200:
#         print("请求成功")
#         with open('./yz.html','w',encoding='utf-8') as fp:
#             fp.write(res.text)
#     filepath='./yz.html'
#     return filepath
#
# def  data_slove(filepath):
#     #解析数据
#     html=etree.parse('./yz.html',etree.HTMLParser())
#     #提取数据 文章标题、文章地址url
#     title=html.xpath('/html/body/div[12]/div/div/main/div[3]/div[1]/div/div[2]/h2/a/span/span/text()')
#     auter=html.xpath('/html/body/div[12]/div/div/main/div[3]/div[1]/div/div[1]/div/div[2]/p/a/span/span/text()')
#     auters=[]
#     #对于数据的清洗
#     for i in auter:
#         auters.append(i.strip())
#         print(auters)
#     data=html.xpath('/html/body/div[12]/div/div/main/div[1]/div[2]/div[1]/div/div[2]/a/time/span/span/text()')
#     a=zip(title,auters,data)
#     content=[]
#     for i,j,k in a:
#         print()
#         b={"标题":i,'作者':j,'日期':k}
#         content.append(b)
#     print(content)
#     return content
# def data_write(content):
#     with open('./data.json','w',encoding='utf-8') as fp:
#         fp.write(json.dumps(content))
#         print("数据加载完成!")
#
# if __name__=='__main__':
#     file_path=data_get()
#     content=data_slove(file_path)
#     data_write(content)


'''
对于beautifulsoup的学习,是另外一个解析html、xml文件插件。
'''

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>

<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>

<p class="story">...</p>
"""

from bs4 import BeautifulSoup as bs4

soup=bs4(html_doc,'html.parser')
# print(soup.prettify())
# print(soup.title)
# print(soup.title.name)
# print(soup.title.parent)
# print(soup.find_all('a'))
# print(soup.a)
# print(soup.find_all('a'))
# print(soup.find(id='link2'))
# print(soup.get_text())

#从文档中找到所有的<a>的标签的链接
# b=[]
# for link in soup.find_all('a'):
#     # print(link)
#     a=link.get('href')
#     b.append(a)
# print(b)

#使用css选择器进行html中数据挑选
# r=soup.select('title')
# print(r)

'''
beautifulsoup4实战,继续数据的爬取
采用两种方法实现数据的爬取:
1)采用xpath解析数据,进行数据的爬取
2)采用beautifulsoup4()进行数据解析,获取数据
'''
# import requests,json
# from lxml import etree
# from bs4 import BeautifulSoup as bs4
# from bs4 import BeautifulSoup as bs4
#
# #请求数据
# def data_get():
#     url='https://www.lmonkey.com/t'
#     headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
#     res=requests.get(url=url,headers=headers)
#     if res.status_code==200:
#         print("请求成功")
#         with open('./bs4.html','w',encoding='utf-8') as fp:
#             fp.write(res.text)
#     return True
#
# #采用xpath爬取数据
# def data_jx():
#     #解析数据
#     html=etree.parse('./bs4.html',etree.HTMLParser())
#     print("**********")
#     title=html.xpath('//*[@id="substories"]/div/div/div[2]/h2/a/span/span/text()')
#     auter=html.xpath('//*[@id="substories"]/div/div/div[1]/div/div[2]/p/a/span/span/text()')
#     date=html.xpath('/html/body/div[12]/div/div/main/div[3]/div/div/div[1]/div/div[2]/a/time/span/span/text()')
#     #数据预处理
#     auters=[]
#     for i in auter:
#         auters.append(i.strip())
#     a=zip(title,auters,date)
#     b=[]
#     for i,j,k in a:
#         b.append({'title':i,'auter':j,'date':k})
#     return b
#     print(b)
# def data_write(data):
#     with open('./data1.json','w') as fp:
#         print("数据正在写入中...")
#         fp.write(json.dumps(data))
#         print("数据写入完成")
#
#         return True
#
# #采用beautifulsoup4爬取数据,bs4的方法不是很好用,;
# def data_bs4_jx():
#     with open('./bs4.html','r',encoding='utf-8') as tf:
#         data=tf.read()
#         # print(data)
#         res=bs4(data,'html.parser')
#         res1=res.find_all('span',style="vertical-align: inherit;")
#         print(res1)
# if __name__=='__main__':
#     data=data_jx()
#     data_write(data)
#     data_bs4_jx()

'''
Re正则表达:就是使用字符、转义字符和特殊字符组成一个规则,使用这个规则对于文本内容完成一个搜索或者匹配或者替换的功能。
正则化表达式的组成:
普通字符:大小写字母、数字、符号等
转移字符:\w \W \d \D等
特殊字符:* + ¥ ?[] {} ()
匹配模式:I U

re模块使python语言拥有全部的的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换

re.match:从字符串的首位开始匹配,起始位置匹配成功则返回,不成功则返回none;
re.search:从字符串的首位一直匹配到末尾,没有匹配到则返回none;
其中返回的结果res.group()则将匹配的字符串返回,res.span()则返回匹配上字符串的下标。
re.findall() 获取字符串中所有搜索的字符,返回一个列表
re.finditer() 获取字符串中所有搜索的字符,返回一个迭代器
'''
# import re
# a='jdeni jdoeo3 jde3 nipoed3je24-3252'
# b='ni'
# b1='jd'
# #使用re.match,从字符串的首位进行匹配,匹配到就返回,没匹配到返回为空
# res=re.match(b1,a)
# print(res.group())
# print(res.span())
# #使用re.search,全局进行搜索,但是返回第一次匹配到的
# res1=re.search(b,a)
# print(res1.span())
#
# #re.findall()搜索出全部字符,返回一个列表
# res2=re.findall(b,a)
# print(res2)
#
# #re.finditer() 所有出全部字符,返回一个迭代器
# res3=re.finditer(b,a)
# for i in res3:
#     print(i.span())
#
# #替换 re.sub(),将匹配到的所有字符进行替换
# res4=re.sub(b,'AAA',a)
# print(res4)
#
# #定义正则化
# patter=re.compile('\d{3}')
# lines=[
#     'i love 2512 jdje',
#     'i live 2365 hdnh',
#     'i love 2356 dheb'
# ]
# b=[]
# for i in lines:
#     res5=patter.search(i).group()
#     b.append(res5)
# print(b)

'''
正则表达式的规则定义:
普通字符:
转义字符:\w \W \d \D \s  \S
#特殊字符: . * + ? [] {} ^ $

'''
# #转义字符:\w \W \d \D \s  \S
# import re
# varstr='$632ile3 der __hde3'
# reg='\w'  #代表单个字母、数字、下滑线
# # reg='\W'      #表单个非字母、数字、下滑线
# # reg='\d'      #表单个数字
# # reg='\D'      #表单个非数字
# # reg='\s'      #表单个空格符或者制表符
# # reg='\S'      #表单个非空格符或者制表符
# res=re.search(reg,varstr).group()
# print(res)

#特殊字符: . * + ? [] {} ^ $
# import re
# varstr='ab3cd ef12346hell %o632ile3 der __hde3'
# b='23654125365122365'
# reg='.'  #代表单个任意字符,除了换行符之外
# reg='\w*'      # *代表匹配次数,任意次数
# reg='\w+'      #+代表匹配次数,至少要求匹配一次
# reg='\w+?'      #?表示拒绝贪婪,就是前面的匹配规则只要达成就返回
# reg='\w*?'      #
# reg='\w{4,7}'      #{}代表匹配次数,
# reg='[0-9]'      #[]代表范围,
# reg='\w+\w'      #{}代表子组,括号中的表达式首先作为整个正则的一部分,另外会把整个符合小括号的内容单独提取一份
# reg='^1\d{10}$'
# res=re.search(reg,varstr)
# print(res)

# '''
# 采用正则化进行数据爬取
# 爬取学习猿地中原创博客:标题、作者、日期、点赞次数
# '''
# import  requests,json,re
# from lxml import etree
#
# #请求响应
# def data_get():
#     url='https://www.lmonkey.com/t'
#     headers={
#         'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#     }
#     res=requests.get(url=url,headers=headers)
#     print(res.text)
#     # if res.status_code==200:
#     #     print('响应请求成功!')
#     #     with open('./ze.html','w',encoding='utf-8') as fp:
#     #         fp.write(res.text)
#     with open('./ze.html','r',encoding='utf-8') as fp:
#         content=fp.read()
#         print(content)
#         #获取标题
#         title='<span style="vertical-align: inherit;"> (.*?)</span>'
#         res2=re.findall(title,content)
#         print(res2)
#         b=[]
#         for i in  res2:
#             a={'content':i}
#             b.append(a)
#         print(b)
#         print(len(res2))
#
# if __name__=='__main__':
#     data_get()

'''
1、爬虫进阶:有道翻译
url='https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rulew'
post 请求
data={
'i':'需要翻译的内容,
’doctypel':'json'}
'''
'''
功能:对于有道翻译进行爬取,采用送入待翻译的内容,将翻译的结果进行爬取,并且展示出来,写入文件中。
'''
# import requests
#
# url='https://fanyi.youdao.com/translate?smartresult=dict&smartresult=rulew'
#
# headers={
#     'User_Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
# }
# content=input("请输入翻译的内容:")
# # print(type(content))
# #定义请求数据
# data={
#     'i':content,
#     'doctype':'json'
# }
#
# #发送请求post
# res=requests.post(url=url,data=data,headers=headers)
# #查看请求结果
# code=res.status_code
# # print("请求状态:",code)
# if code==200:
#     # print("请求内容:",res.text)
#     resdata=res.json()
#     if resdata['errorCode']==0:
#         # print("结果请求成功")
#         contents=resdata['translateResult'][0][0]['tgt']
#         print("翻译结果:",contents)
#         with open('./youdao.txt','w',encoding='utf-8') as fp:
#             fp.write(content+'\n'+contents)
#             print("数据写入成功。")

'''
代理IP的出现:当某个IP频繁访问网站,一方面对于当前网站有着很大的访问压力,另外有盗取别人数据的嫌疑,因此出现代理IP来为伪装自己的爬虫访问。
如何破解这个访问?
1、推荐访问:降低爬虫请求频率;
2、使用代理IP;
代理IP的分类:一般分成三类透明代理、普通匿名代理、高级匿名代理
透明代理:服务端可以知道你使用了IP,并且知道使用的真实IP;
普通匿名代理:服务器知道使用了IP,但是不知道真实IP;
高级匿名代理:隐藏了本机真实IP,并且访问对象也不知道你使用了代理IP,属于隐藏度最高的。
代理IP的网站:西祠代理、快代理、89代理、豌豆代理、66代理、蘑菇代理、熊猫代理、站大爷等
'''
'''
实战:代理IP进行数据爬取
'''
# import requests,json
#
# #发起请求
# url='http://httpbin.org/get'
# headers={
#     'User_Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
# }
# #代理IP
# proxies={
#     'http':'183.147.26.107:9000',
#     'https':'183.147.26.107:9000'
# }
#
# res=requests.get(url=url,headers=headers,timeout=5)
# print(res.text)
# if res.status_code==200:
#     print("请求成功!")
#     res=res.json()['origin']
#     print(res)

'''
实战:
缺点:只能爬取首页(代码中,对于分页爬取将考虑进去。)
1、爬取代理IP网站的IP和端口,并且写入到文件中;
2、对于爬取的IP和端口,进行实际网页爬取,获取通的ip和端口以及不通的端口
'''
# import requests,json
# from lxml import etree
# import pandas as pd
# def get_data(i):
#     #发送请求
#     url='https://www.kuaidaili.com/free/inha/'+str(i)+'/'
#     #伪装爬虫
#     headers={
#         'User_Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#     }
#
#     res=requests.get(url=url,headers=headers)
#     if res.status_code==200:
#         print('请求成功')
#         with open('./dailipq.html','w',encoding='utf-8') as fp:
#             fp.write(res.text)
#             print('数据写入成功')
#     return True
# #解析数据
# def parse_data():
#     html=etree.parse('./dailipq.html',etree.HTMLParser(),)
#     ip=html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[1]/text()')
#     port=html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[2]/text()')
#     nmd = html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[3]/text()')
#     type = html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[4]/text()')
#     postive = html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[5]/text()')
#     xysj = html.xpath('/html/body/div/div[4]/div[2]/div[2]/div[2]/table/tbody/tr/td[6]/text()')
#
#     DataFrame=pd.DataFrame(columns=['ip','端口','匿名程度','类型','位置','响应时间'])
#
#     data=pd.concat([DataFrame,pd.DataFrame({
#         'ip':ip,
#         '端口':port,
#         '匿名程度':nmd,
#         '类型':type,
#         '位置':postive,
#         '响应时间':xysj
#     })])
#     # print(data)
#     data.to_csv('./dalii.csv',mode='a')
#     return data
#
#
# def datapaq():
#     #利用爬取的IP进行数据爬取,一方面验证哪些IP可以使用,另外一方面进行数据的爬取;
#     data=pd.read_csv('./dalii.csv')
#     ip_port=data[['ip','端口']]
#     ip_port=ip_port.drop_duplicates(['ip','端口'], keep="first", inplace=False)
#
#     # print(ip_port)
#     for a,b in zip(ip_port['ip'],ip_port['端口']):
#         #发起请求
#         url='http://httpbin.org/get'
#         headers={
#             'User_Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
#         }
# #         #代理IP
#         proxies={
#             'http':a+':'+b,
#             'https':a+':'+b
#         }
#         try:
#             res=requests.get(url=url,headers=headers,proxies=proxies,timeout=5)
#             if res.status_code==200:
#                 print('IP:'+a+',端口:'+b+'测试通过。')
#                 print("请求成功!")
#                 res=res.json()['origin']
#                 print(res)
#         except:
#             print('IP:'+a+',端口:'+b+'  测试不通过。')
#
# if __name__=='__main__':
#     for i in range(1,3,1):
#         get_data(i)
#         data=parse_data()
#     datapaq()

'''
进程与线程:
进程:原理上计算机一个核只可以运行一个进程,但是即使在计算机早期单核的时候,计算机也运行着多个进行,但是由于计算机运行速度快,它自由贴换运行多个
进程,让人感觉不到,但是本质一个核智能运行一个进行,但是现阶段一个电脑有多个核心,即可以运行多个进行。
线程:一个进程中至少有多个线程,完成一个进程的不同部分任务,一个工厂就好比一个进程,里面至少有一个人去完成工作。
进程和线程之间采用协调机制,实现空间共享,同时对于空间问题采用锁的机制保证线程有序进行处理。
'''
'''
爬虫实战:图片爬取
'''
import requests
import os
import urllib


class Spider_baidu_image():
    def __init__(self):
        self.url = 'http://image.baidu.com/search/acjson?'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.\
            3497.81 Safari/537.36'}
        self.headers_image = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.\
            3497.81 Safari/537.36',
            'Referer': 'http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fm=result&fr=&sf=1&fmq=1557124645631_R&pv=&ic=&nc=1&z=&hd=1&latest=0&copyright=0&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E8%83%A1%E6%AD%8C'}
        self.keyword = input("请输入搜索图片关键字:")
        self.paginator = int(input("请输入搜索页数,每页30张图片:"))


    def get_param(self):
        """
        获取url请求的参数,存入列表并返回
        :return:
        """
        keyword = urllib.parse.quote(self.keyword)
        params = []
        for i in range(1, self.paginator + 1):
            params.append(
                'tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord={}&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=&hd=1&latest=0&copyright=0&word={}&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&cg=star&pn={}&rn=30&gsm=78&1557125391211='.format(
                    keyword, keyword, 30 * i))
        return params

    def get_urls(self, params):
        """
        由url参数返回各个url拼接后的响应,存入列表并返回
        :return:
        """
        urls = []
        for i in params:
            urls.append(self.url + i)
        return urls

    def get_image_url(self, urls):
        image_url = []
        for url in urls:
            json_data = requests.get(url, headers=self.headers).json()
            json_data = json_data.get('data')
            for i in json_data:
                if i:
                    image_url.append(i.get('thumbURL'))
        return image_url

    def get_image(self, image_url):
        """
        根据图片url,在本地目录下新建一个以搜索关键字命名的文件夹,然后将每一个图片存入。
        :param image_url:
        :return:
        """
        cwd = os.getcwd()
        file_name = os.path.join(cwd, self.keyword)
        if not os.path.exists(self.keyword):
            os.mkdir(file_name)
        for index, url in enumerate(image_url, start=1):
            with open(file_name + '\\{}.jpg'.format(index), 'wb') as f:
                f.write(requests.get(url, headers=self.headers_image).content)
            if index != 0 and index % 30 == 0:
                print('{}第{}页下载完成'.format(self.keyword, index / 30))

    def __call__(self, *args, **kwargs):
        params = self.get_param()
        urls = self.get_urls(params)
        image_url = self.get_image_url(urls)
        self.get_image(image_url)


if __name__ == '__main__':
    spider = Spider_baidu_image()
    spider()











おすすめ

転載: blog.csdn.net/zhangzhoubin666/article/details/121283912