一、什么是requests 模块
requests模块是python中原生的基于网络请求的模块,功能强大,用法简洁高效。在爬虫领域中占据着半壁*的地位。requests模块作用:模拟浏览器发请求。
二、为什么要使用requests 模块
因为在使用urllib模块的时候,会有诸多不便之处,总结如下:
- 手动处理url编码
- 手动处理post请求参数
- 处理cookie和代理操作繁琐
- ......
而使用requests模块的优势:
- 自动处理url编码
- 自动处理post请求参数
- 简化cookie和代理操作
- ......
三、如何使用requests模块
安装: pip install requests
使用流程
- 指定url
- 基于requests模块发起请求
- 获取响应对象中的数据值
- 持久化存储
requests 模块的各种请求方式
最常用的请求方式就是 post 和 get 请求。params 在 get 请求中使用,data、json在post请求中使用。自动和url进行拼接,发请求。
response = requests.get(url, params={\'key\':\'value\'})
response = requests.post(url, data={\'key\':\'value\'})
请求参数
通常请求参数有以下几个
- url :需要抓取的URL地址
- headers : 请求头
- timeout : 超时时间,超过时间会抛出异常
下面,再分享2个其他可能会遇到的参数,关于非常重要的IP参数,在后面进行讲解。
(1)authWeb客户端验证参数
res = requests.get(url, headers=headers, auth=(\'username\',\'password\'))
针对于需要web客户端用户名密码认证的网站
例如:
import requests from lxml import etree import random import os class CodeSpider(object): def __init__(self): self.url = \'http://code.tarena.com.cn/AIDCode/aid1904/14-redis/\' self.auth = (\'tarenacode\', \'code_2013\') self.ua_list = [ \'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1\', \'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0\', \'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .\ NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3)\', ] def parse_html(self): # 获取响应内容 html = requests.get(url=self.url, headers={\'User-Agent\': random.choice(self.ua_list)}, auth=self.auth) html = html.content.decode(\'utf-8\', \'ignore\') parse_html = etree.HTML(html) r_list = parse_html.xpath(\'//a/@href\') # # r_list : [\'../\',\'day01\',\'day02\',\'redis_day01.zip\'] for r in r_list: if r.endswith(\'.zip\') or r.endswith(\'.rar\'): self.save_files(r) def save_files(self, r): directory = \'/home/tarena/AID/redis/\' if not os.path.exists(directory): os.makedirs(directory) # 拼接地址,把zip文件保存到指定目录 url = self.url + r # filename: /home/tarena/AID/redis/xxx.zip filename = directory + r html = requests.get(url=url, headers={\'User-Agent\': random.choice(self.ua_list)}, auth=self.auth).content with open(filename, \'wb\') as f: f.write(html) print(\'%s下载成功\' % r) if __name__ == \'__main__\': spider = CodeSpider() spider.parse_html()
(2)SSL证书认证参数-verify
SSL证书认证参适用于没有经过证书认证机构认证的https类型网站,如果网站抛出 SSLError 异常,则考虑使用此参数。
response = requests.get(url=url,params=params,headers=headers,verify=False)
verify:
- True ( 默认 ) 检查证书认证;
- False(常用)忽略证书认证;
响应对象response的属性
- text :返回的是Unicode型的数据;取html源码;
- content :返回的是bytes型也就是二进制的数据。取图片,文件;
- json() : 返回的是json格式数据;
- status_code :HTTP响应码;
- encoding :响应字符编码 response.encoding = \'utf-8\';
非结构化数据的保存方式。如压缩文件zip、图片文件等都可以使用非结构化数据的保存方式
with open(\'xxx.jpg\',\'wb\') as f: f.write(response.content)
四、User-Agent *****
通过自定义请求对象,用于伪装爬虫程序请求的身份。
User-Agent参数,简称为UA,该参数的作用是用于表明本次请求载体的身份标识。如果我们通过浏览器发起的请求,则该请求的载体为当前浏览器,则UA参数的值表明的是当前浏览器的身份标识表示的一串数据。如果我们使用爬虫程序发起的一个请求,则该请求的载体为爬虫程序,那么该请求的UA为爬虫程序的身份标识表示的一串数据。有些网站会通过辨别请求的UA来判别该请求的载体是否为爬虫程序,如果为爬虫程序,则不会给该请求返回响应,那么我们的爬虫程序则也无法通过请求爬取到该网站中的数据值,这也是反爬虫的一种初级技术手段。为了防止该问题的出现,则我们可以给爬虫程序的UA进行伪装,伪装成某款浏览器的身份标识。
UA检测:网站服务器会检测请求的载体身份标识,如果检测到是基于爬虫程序的,则阻止该次请求。
UA伪装(反爬机制):
反爬机制:某些门户网站会对访问该网站的请求中的User-Agent进行捕获和判断,如果该请求的UA为爬虫程序,则拒绝向该请求提供数据。
反反爬策略:将爬虫程序的UA伪装成某一款浏览器的身份标识。
import requests
url = \'http://www.baidu.com/\'
headers={
\'User-Agent\' : \'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\'
}
request =request.get(url=url,headers=headers)
找到User-Agent,复制下来。
五、requests 模块使用实例
1 基于requests模块的get请求
示例:爬取搜狗指定词条搜索后的页面数据 (网页采集器, 动态获取)
1 import requests
2 word = input(\'enter a word:\')
3 url = \'https://www.sogou.com/web\'
4
5 headers = {
6 \'User-Agent\':\'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\'
7 }
8
9 param = {
10 \'query\':word
11 }
12
13 response = requests.get(url=url,params=param)
14 page_text = response.text
15
16 fileName = word+\'.html\'
17 with open(fileName,\'w\',encoding=\'utf-8\') as fp:
18 fp.write(page_text)
19
20 print(fileName,\'爬取成功!\')
2 基于requests模块的post请求
示例:登录豆瓣电影,爬取登录成功后的页面数据
1 import requests
2 import os
3
4 url = \'https://accounts.douban.com/login\'
5
6 data = {
7 "source": "movie",
8 "redir": "https://movie.douban.com/",
9 "form_email": "131XXXXXXXX",
10 "form_password": "***",
11 "login": "登录",
12 }
13
14 headers={
15 \'User-Agent\': \'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\',
16 }
17
18 response = requests.post(url=url,data=data)
19 page_text = response.text
20 with open(\'./douban111.html\',\'w\',encoding=\'utf-8\') as fp:
21 fp.write(page_text)
3 基于requests模块ajax的get请求
示例:爬取豆瓣电影分类排行榜中的电影详情数据
1 import requests
2 headers = {
3 \'User-Agent\':\'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'
4 }
5 url = \'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20\'
6
7 movie_list = requests.get(url=url,headers=headers).json()
8
9 all_names = []
10 for dic in movie_list:
11 name = dic[\'title\']
12 all_names.append(name)
13
14 print(all_names)
4 基于requests模块ajax的post请求
示例:破解百度翻译
1 import requests
2
3 url = \'https://fanyi.baidu.com/sug\'
4 wd = input(\'enter something of English:\')
5 data = {
6 \'kw\':wd
7 }
8
9
10 headers = {
11 \'User-Agent\':\'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\'
12 }
13
14 response = requests.post(url=url,data=data,headers=headers)
15
16 obj_json = response.json()
17 print(obj_json)
综合练习:爬取国家药品监督管理总局中基于*化妆品生产许可证相关数据
1 import requests
2 from fake_useragent import UserAgent
3
4 ua = UserAgent(use_cache_server=False,verify_ssl=False).random
5 headers = {
6 \'User-Agent\':ua
7 }
8
9 url = \'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList\'
10
11 all_id_list = []
12
13 for page in range(1,11):
14 data = {
15 \'on\': \'true\',
16 \'page\': str(page),
17 \'pageSize\': \'15\',
18 \'productName\':\'\',
19 \'conditionType\': \'1\',
20 \'applyname\':\'\',
21 \'applysn\':\'\'
22 }
23
24 json_text = requests.post(url=url,data=data,headers=headers).json()
25 for dict in json_text[\'list\']:
26 id = dict[\'ID\']
27 all_id_list.append(id)
28
29
30 post_url = \'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById\'
31 for id in all_id_list:
32 post_data = {
33 \'id\': id
34 }
35 response = requests.post(url=post_url, data=post_data, headers=headers)
36
37 if response.headers[\'Content-Type\'] == \'application/json;charset=UTF-8\':
38 json_text = response.json()
39 print(json_text[\'businessPerson\'])
查看是不是动态加载页面,就在开发者工具中的response中搜索。不能搜到就证明是动态加载出来的。
其他概念:
- 结构化数据:即行数据,存储在数据库里,可以用二维表结构来逻辑表达实现的数据。
- 非结构化数据:包括所有格式的办公文档、文本、图片、XML、HTML、各类报表、图像和音频/视频信息等等。