04 Python网络爬虫 <<爬取get/post请求的页面数据>>之requests模块
一. urllib库
urllib是python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求。其常被用到的子模块在python3中的为urllib.request和urllib.parse,在python2中就是urllib和urllib2。
二.requests库
- 安装: pip install requests
- 作用: 就是用来模拟浏览器上网的
- 特点: 简单高效
- 使用流程:
* 指定url
* 发起请求
* 获取响应数据
* 持久化存储
三.爬取简单的网页
普通get请求
1 # 爬取搜狗首页的页面数据 2 import requests 3 # 第一步指定url 4 url = 'https://www.sogou.com/' 5 # 第二步发送请求 6 response = request.get(url=url) 7 # 第三步获取响应数据 8 page_text = response.text #text返回的是字符串类型的数据(由响应体中的content-type,也可以是json) 9 # 第四步持久化存储 10 with open('./souhu.html','w',encoding='utf-8') as fp: 11 fp.write(page_text) 12 13 print('搜狗首页爬取完毕!!!')
普通post请求
请求载体身份标识的伪装:
-
-
user-agent:请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的user-agent为浏览器的身份标识,使用爬虫程序发起的请求,则该请求的载体为爬虫程序,则该请求的user-agent为爬虫程序的身份标识。可以通过判断该值来获知该请求的载体究竟是基于哪款浏览器还是基于爬虫程序。
-
反爬机制:某些门户网站会对访问该网站的请求中的user-agent进行捕获和判断,如果该请求的ua为爬虫程序,则拒绝向该请求提供数据。
-
反反爬策略:将爬虫程序的ua伪装成某一款浏览器的身份标识
-
# 普通post请求
import requests
import os
url = 'https://accounts.douban.com/login'
#封装请求参数
data = {
"source": "movie",
"redir": "https://movie.douban.com/",
"form_email": "15027900535",
"form_password": "bobo@15027900535",
"login": "登录",
}
#自定义请求头信息
headers={
'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'
}
response = requests.post(url=url,data=data)
page_text = response.text with open('./douban111.html','w',encoding='utf-8') as fp:
fp.write(page_text)
ajax的post请求:
- 爬取肯德基任意城市的位置信息
1 #爬取任意城市对应的肯德基餐厅的位置信息 2 #动态加载的数据 3 city = input('enter a cityname:') 4 url = 'http://www.kfc.com.cn/kfccda/ashx/getstorelist.ashx?op=keyword' 5 data = { 6 "cname": "", 7 "pid": "", 8 "keyword": city, 9 "pageindex": "2", 10 "pagesize": "10", 11 } 12 #ua伪装 13 headers = { 14 'user-agent':'mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.77 safari/537.36' 15 } 16 response = requests.post(url=url,headers=headers,data=data) 17 18 json_text = response.text 19 20 print(json_text)
普通post请求
- 爬取百度翻译输入任意内容翻译出来的结果
1 #破解百度翻译 2 url = 'https://fanyi.baidu.com/sug' 3 word = input('enter a english word:') 4 #请求参数的封装 5 data = { 6 'kw':word 7 } 8 #ua伪装 9 headers = { 10 'user-agent':'mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.77 safari/537.36' 11 } 12 response = requests.post(url=url,data=data,headers=headers) 13 #text:字符串 json():对象 14 obj_json = response.json() 15 16 print(obj_json)
ajax的get请求
需求:爬取豆瓣电影分类排行榜 中的电影详情数据
1 import requests 2 import urllib.request 3 if __name__ == "__main__": 4 5 #指定ajax-get请求的url(通过抓包进行获取) 6 url = 'https://movie.douban.com/j/chart/top_list?' 7 8 #定制请求头信息,相关的头信息必须封装在字典结构中 9 headers = { 10 #定制请求头中的user-agent参数,当然也可以定制请求头中其他的参数 11 'user-agent': 'mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/66.0.3359.181 safari/537.36', 12 } 13 14 #定制get请求携带的参数(从抓包工具中获取) 15 param = { 16 'type':'5', 17 'interval_id':'100:90', 18 'action':'', 19 'start':'0', 20 'limit':'20' 21 } 22 #发起get请求,获取响应对象 23 response = requests.get(url=url,headers=headers,params=param) 24 25 #获取响应内容:响应内容为json串 26 print(response.text)
四. 爬取较难的数据
- 步骤分析:
1. 通过抓包工具检测出首页中的企业信息数据全部为动态加载
2. 通过抓包工具获取了动态加载数据对应的ajax的数据包(url,请求参数)
3. 通过对步骤2的url请求后获取的响应数据中分析出有一个特殊的字段id(每家企业都有一个唯一的id值)
4. 从手动点击企业进入企业的详情页,发现浏览器地址栏中的url中包含了该企业的id,使用企业id和固定的域名可以拼接成详情页的url
5. 发现详情页的企业详情信息对应的数据值是动态加载出来的。上述我们获取详情页的url是无用的。
6. 通过抓包工具的全局搜索的功能,可以定位到企业详情信息对应的ajax数据包(url,请求参数),对应的响应数据就是最终我们想要爬取的企业详情数据。
1 # http://125.35.6.84:81/xk/ 爬取每家企业的企业详情数据 2 3 import requests 4 headers = { 5 'user-agent':'mozilla/5.0 (windows nt 6.1; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.77 safari/537.36' 6 } 7 first_url = 'http://125.35.6.84:81/xk/itownet/portalaction.do?method=getxkzslist' 8 ids = [] 9 for page in range(1,11): 10 data = { 11 "on": "true", 12 "page": str(page), 13 "pagesize": "15", 14 "productname": "", 15 "conditiontype": "1", 16 "applyname": "", 17 "applysn": "", 18 } 19 response = requests.post(url=first_url,data=data,headers=headers) 20 #response.headers返回的是响应头信息(字典) 21 if response.headers['content-type'] == 'application/json;charset=utf-8': 22 json_obj = response.json() 23 for dic in json_obj['list']: 24 ids.append(dic['id']) 25 26 detail_url = 'http://125.35.6.84:81/xk/itownet/portalaction.do?method=getxkzsbyid' 27 for _id in ids: 28 data = { 29 'id':_id 30 } 31 company_text = requests.post(detail_url,data=data,headers=headers).text 32 print(company_text)
五 . 补充踩过的坑:
get请求参数有 url params headers
post请求参数 url data headers
使用urllib爬取数据请参考: