一、urllib模块-(了解即可,用的不多)
二、requests模块
2.0、requests模块--response的方法
2.1、基于requests模块发起get请求
2.2、基于requests模块发起get请求(带参数)
2-3、基于requests模块发起get请求(自定义请求头)
2-4、基于requests模块发起post请求(请求头content-type=application/x-www-form-urlencoded)
2-4(1)、基于requests模块发起post请求(请求头content-type=multipart/form-data)上传文件
2-4(2)、基于requests模块发起post请求(请求头content-type=application/json)
2-5、基于requests模块发起ajax(get)请求-略
2-6、基于requests模块发起ajax(post)请求-略
2-7、requests模块综合练习
三、requests模块高级(cookie, 代理)
3.1、cookie
3.2、cookie操作:获取某用户的个人主页(先登录再获取)
3.3、代理(正向代理)
3.4、代理操作:更换IP然后向百度搜索的IP关键字发请求,看IP所在地
四、验证码处理-打码平台
=============================================================================================
robots.txt协议
是网站规定的哪些数据可以爬取,哪些不能爬取,不是强制遵守的
例如:淘宝的www.taobao.com/robots.txt
一、urllib模块-(了解即可,用的不多)
urllib、requests模块,主要使用requests模块
数据爬取步骤:
1、指定url
2、发请求
3、获取页面数据
4、持久化存储
需求1:爬取搜狗首页---(无参数GET请求)
import urllib.request
url = 'https://www.baidu.com/' # 请求url
response = urllib.request.urlopen(url=url)
page_text = response.read() # bytes类型的页面数据
with open('./sougou.html','wb') as fp:
fp.wirte(page_text)
print('写入数据成功')
需求2;爬取指定词条对应的数据---(有参数GET请求,参数为中文)
import urllib.request
import urllib.parse
# url = 'https://www.baidu.com/s?wd=哈哈'
# 请求url中存在非ASCII编码的字符数据,会出错,要转码再拼接
word = urllib.parse.quote("哈哈")
url = 'https://www.baidu.com/s?wd=' + word
response = urllib.request.urlopen(url=url)
page_text = response.read() # bytes类型的页面数据
with open('./sougou.html','wb') as fp:
fp.wirte(page_text)
print('写入数据成功')
需求3:反爬机制:网站检查请求的UA---(GET请求,指定请求头)
User-Agent(UA):浏览器身份标识
反反爬机制:UA伪装,请求头的"User-Agent"
UA伪装:
import urllib.request
url = "https://www.baidu.com/"
headers = {
"User-Agent": "Mozilla/5.0"
}
request = urllib.request.Request(url=url,headers=headers)
response = urllib.request.urlopen(request)
page_text = response.read()
with open('./sougou.html','wb') as fp:
fp.wirte(page_text)
print('写入数据成功')
post请求携带参数进行处理
1.将post请求参数封装到字典
2.使用parse模块中的urlencode进行编码处理(返回值类型为str)
3.将第二步获取的编码结果转换为bytes类型
4.发起post请求:urlopen函数的data参数就是经过处理的post请求携带请求数据
需求4:爬取百度翻译的翻译结果(POST请求)
import urllib.request
import urllib.parse
url = 'https://fanyi.baidu.com/sug'
data = {
'kw':'西瓜'
}
data = urllib.parse.urlencode(data)
data = data.encode()
response = urllib.request.urlopen(url=url, data=data)
response.read()
需求5:urllib高级操作,一般不用,太繁琐
参考http://www.xiaobaibook.com/details/51/
1、代理
2、cookie
二、requests模块
requests模块功能强大,使用方便,掌握了requests就掌握了爬虫的半壁江山
安装:pip install requests
五个项目学习和巩固requests模块:
- get
- post
- ajax(get)
- ajax(post)
- 综合
2.0、requests模块--response的方法
------------------------------------
response.text : 字符串形式的页面数据
response.content : 二进制形式的页面数据
response.status_code : 响应状态码
response.headers : 响应头信息
response.url : 本次请求的url
------------------------------------
2.1、基于requests模块发起get请求
例如:爬取百度首页的页面数据
import requests
url = "https://www.baidu.com/"
# 返回请求成功的响应对象
response = requests.get(url=url)
# 获取响应对象中的数据
page_text = response.text
with open('./sougou.html','wb',encoding="utf8") as fp:
fp.wirte(page_text)
print('写入数据成功')
2.2、基于requests模块发起get请求(带参数)
例如:爬取百度搜索词条的搜索结果
方法一:参数拼接在url里
import requests
url = 'https://www.baidu.com/s?wd=哈哈'
response = requests.get(url=url)
方法二:参数放在get方法里
import requests
url = 'https://www.baidu.com/s'
params = {
"wd":"哈哈"
}
response = requests.get(url=url, params=params)
2-3、基于requests模块发起get请求(自定义请求头)
import requests
url = "https://www.baidu.com/"
headers = {
"User-Agent": "Mozilla/5.0"
}
response = requests.get(url=url, headers=headers)
2-4、基于requests模块发起post请求(请求头content-type=application/x-www-form-urlencoded)
例如:登录豆瓣网,获取登录成功后的页面数据
import requests
url = "https://movie.douban.com/login/"
data =
"source":"movie",
"redir":"https://movie.douban.com/",
"form_email":15203949239,
"form_password":hh12345,
"login":"登录",
}
headers = {
"User-Agent": "Mozilla/5.0"
}
requests.post(url=url,data=data,headers=headers)
2-4(1)、基于requests模块发起post请求(请求头content-type=multipart/form-data)上传文件
import requests,json url_mul = 'http://httpbin.org/post' files = {'file':open('E://report.txt','rb')} r = requests.post(url_mul,files=files) print(r) print(r.text) print(r.content)
2-4(2)、基于requests模块发起post请求(请求头content-type=application/json)
def fzjg(): ''' 分支机构 :return: ''' api = '/api/v1.0/company/basic/query/fzjg' url = 'http://xfrm.safe.gov.cn/api/v1.0/company/basic/query/fzjg' data = { "pageNum": '1', "pageSize": '10', "qyxxId": globals()['ID'], } headers = { "Content-Type": "application/json" } response = requests.post(url=url, data=json.dumps(data), headers=headers) qs = json.loads(response.text) # print(qs) print((api, qs['message'], qs['data']))
2-5、基于requests模块发起ajax(get)请求-略
省略。跟requests发get请求一模一样,只是ajax返回的数据长度比较短
2-6、基于requests模块发起ajax(post)请求-略
省略。跟requests发post请求一模一样,只是ajax返回的数据长度比较短
2-7、requests模块综合练习
例如:爬取搜狗->知乎中"人工智能"词条搜索结果前3页的数据
import requests
url = "https://www.sogou.com/sogou
for page in range(1,4):
params = {
"query": "人工智能",
"pid": "sogou-wsse-ff111e4a5406ed40",
"insite": "zhihu.com",
"sut": "3651",
"lkt": "0,0,0",
"sst0": "1561710969623",
"page": "2",
"duppid": "1",
"ie": "utf8",
}
response = requests.get(url,params=params)
print(response.text)
三、requests模块高级
3.1、cookie
1.执行登录操作(获取cookie)
2.在发起个人主页请求时,需要将cookie携带到该请求中
登录的时候服务器发送的cookie存放在浏览器session中。
3.2、cookie操作:获取某用户的个人主页(先登录再获取)
import requests
session = requests.session()
url = "https://movie.douban.com/login/"
data =
"source":"movie",
"redir":"https://movie.douban.com/",
"form_email":15203949239,
"form_password":hh12345,
"login":"登录",
}
# 登录
session.post(url=url,data=data,headers=headers)
url="https://www.douban.com/people"
# 个人主页
response = session.get(url=url)
page_text = response.text
3.3、代理(正向代理)
1.爬虫中为什么要使用代理?反反爬手段
2.有些门户网站会监测某IP的次数,次数太快会被禁
3.免费代理IP的网站提供商www.goubanjia.com
3.4、代理操作:更换IP然后向百度搜索的IP关键字发请求,看IP所在地
import requests
# url的协议和proxy的协议保持一致,都为http。
url = 'http://www.baidu.com/s?ie=utf-8&wd=ip'
proxy = {
'http':'77.73.69.120:3128'
}
# 更换网络IP
request = requests.get(url=url,proxies=proxy)
四、验证码处理-打码平台
使用云打码平台自动识别验证码,实现流程:
1.对携带验证码的页面数据进行抓取
2.可以将页面数据中验证码进行解析,验证码图片下载到本地
3.可以将验证码图片提交给第三方平台进行识别,返回验证码图片上的数据值
云打码平台
1,在官网进行注册(普通用户和开发者用户)
2,登录开发者用户
3,在开发文档中下载示例代码(调用示例及最新的dll)
4,下载“pythonHTTP示例下载”
5,创建一个软件:我的软件->添加新软件->提交-产生秘钥数据
6,使用示例代码中的源码文件中的代码进行修改,让其识别验证码图片
7,解压下载的示例代码里面的YDMHTTPDemo3.x.py
8,拷贝YDMHTTPDemo3.x.py中YDMHttp类到你的代码中,注册
9,import json,time 打码平台要用到这两个模块
10,拷贝YDMHTTPDemo3.x.py中剩下的代码,封装到get_img_code(img_obj)方法中
username=你第一步注册的普通用户,里面的剩余题分是你可以识别的次数
password=普通用户的密码
appid = 你的开发者用户的软件代码
appkey = 你的开发者用户的软件秘钥
filename = 你的验证码图片路径
codetype = 验证码类型,例如4位纯英文等
timeout = 超时时间一般为20
return result
import requests
from lxml import etree
url="https://www.douban.com/accounts/login?source=movie"
page_text = requests.get(url=url)
# 获取验证码图片
tree = etree.HTML(page_text)
codeImg_url = tree.xpath('//*[@id="captcha_image"]/@src')[0]
code_img = requests.get(url=codeImg_url).content
with open("./code.png","wb") as fp:
fp.write(code_img)
code_text = getCode('./code.png')
附加知识点:xpath解析HTML代码
1.下载:pip install lxml
2.导包:from lxml import etree
3.将html文档或者xml文档转换成一个etree对象,然后调用对象中的方法查找指定的节点
2.1 本地文件:tree = etree.parse(文件名)
tree.xpath("xpath表达式")
2.2 网络数据:tree = etree.HTML(网页内容字符串)
tree.xpath("xpath表达式")
常用xpath表达式:
属性定位:
#找到class属性值为song的div标签
//div[@class="song"]
取属性:
# 找到class属性值为tang的div标签下第二个li标签下的a标签的href属性值
//div[@class="tang"]//li[2]/a/@href
层级&索引定位:
#找到class属性值为tang的div的直系子标签ul下的第二个子标签li下的直系子标签a
//div[@class="tang"]/ul/li[2]/a
逻辑运算:
#找到href属性值为空且class属性值为du的a标签
//a[@href="" and @class="du"]
模糊匹配:
//div[contains(@class, "ng")]
//div[starts-with(@class, "ta")]
取文本:
# /表示获取某个标签下的文本内容
# //表示获取某个标签下的文本内容和所有子标签下的文本内容
//div[@class="song"]/p[1]/text()
//div[@class="tang"]//text()