python requests模块
什么是requests模块
了解爬虫的人都知道,爬虫总共分为四部分,发送请求,获取响应,解析数据,保存数据,发送请求可能是爬虫的起点,或者说是第一步,更是重点。
而requests模块是python中基于网络请求的模块,或者可以说是发送请求的模块,它通过模拟浏览器发起请求,虽然它的语法相对比较简单,但是它的功能却是十分的强大。
在python3中,python2的urllib2库变成了urllib,但是它还是有很多不便之处。比如:
手动处理url编码,手动处理post请求参数,处理cookie和代理操作繁琐。
然而,requests模块刚好可以解决这些问题。
requests模块支持的请求方式
requests模块中支持所有常见的http请求
requests.get('https://www.xy.org/get')
requests.post('https://www.xy.org/post')
requests.put('https://www.xy.org/put')
requests.delete('https://www.xy.org/delete')
requests.head('https://www.xy.org/get')
requests.options('https://www.xy.org/get')
但是我们常用的也就是get请求和post请求,get请求没有请求体,而post请求有
requests的get请求
import requests
# 这是请求的路径,必须有
url='https://www.baidu.com/'
#这 是本次访问携带的参数,发送请求时,它会以?name=hh的形式加在路径后面,不是必须要有
params={'name':'hh'}
# 这是请求的请求体,它是以键值对的形式存在的,也不是必须要有
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'}
# 这是访问携带的cookie数据
cookies='dshdjdsadhsaghgdasjjdasjdhasdashdjkhskad'
res = requests.get(url=url, headers=headers,params=params,cookies=cookies)
User-Agent:请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,使用爬虫程序发起的请求,则该请求的载体为爬虫程序,则该请求的User-Agent为爬虫程序的身份标识。可以通过判断该值来获知该请求的载体究竟是基于哪款浏览器还是基于爬虫程序。
代码示例:爬取百度指定词条搜素后的页面
import requests
word = input('请输入你要爬取的词条:')
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) "
"Version/5.1 Safari/534.50"}
url = 'https://www.baidu.com/s'
prams = {
'wd': word,
}
res = requests.get(url=url, params=prams, headers=headers)
with open(word + '.html', 'w', encoding='utf-8') as f:
f.write(res.text)
输入关键字 the shy ,得到页面:
requests的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)
由于豆瓣改版可能以上代码不能使用了,但是它还是说明了post请求的使用方法。我会重新写个博客来模拟登录。
基于requests模块ajax的get和post请求
ajax的get请求:爬取豆瓣电影分类排行榜
import requests
if __name__ == "__main__":
#指定ajax-get请求的url(通过抓包进行获取)
url = 'https://movie.douban.com/j/chart/top_list?'
#定制请求头信息,相关的头信息必须封装在字典结构中
headers = {
#定制请求头中的User-Agent参数,当然也可以定制请求头中其他的参数
'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',
}
#定制get请求携带的参数(从抓包工具中获取)
param = {
'type_name':'情色',
'type':'6',
'interval_id':'100:90',
'action':'',
}
#发起get请求,获取响应对象
response = requests.get(url=url,headers=headers,params=param)
#获取响应内容:响应内容为json串
print(response.text)
ajax的post请求:爬取肯德基餐厅查询http://www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数据
import requests
if __name__ == "__main__":
#指定ajax-post请求的url(通过抓包进行获取)
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
#定制请求头信息,相关的头信息必须封装在字典结构中
headers = {
#定制请求头中的User-Agent参数,当然也可以定制请求头中其他的参数
'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',
}
#定制post请求携带的参数(从抓包工具中获取)
data = {
'cname':'西安',
'pid':'31',
'keyword':'雁塔',
'pageIndex': '1',
'pageSize': '10'
}
#发起post请求,获取响应对象
response = requests.post(url=url,headers=headers,data=data)
#获取响应内容:响应内容为json串
print(response.text)
得到结果:
{"Table":[{"rowcount":5}],"Table1":[{"rownum":1,"storeName":"唐延","addressDetail":"雁塔区唐延路3号易初莲花超一层","pro":"24小时,Wi-Fi,店内参观,礼品卡,生日餐会","provinceName":"陕西省","cityName":"西安市"},{"rownum":2,"storeName":"万达","addressDetail":"雁塔路北段8号万达商业广场一二层","pro":"Wi-Fi,店内参观,礼品卡","provinceName":"陕西省","cityName":"西安市"},{"rownum":3,"storeName":"城市立方","addressDetail":"雁塔区朱雀大街南段12号城市立方","pro":"Wi-Fi,点唱机","provinceName":"陕西省","cityName":"西安市"},{"rownum":4,"storeName":"MomoPark","addressDetail":"雁塔区小寨西路232号置地时代MOMOPARK购物中心1、2层肯德基餐厅","pro":"Wi-Fi","provinceName":"陕西省","cityName":"西安市"},{"rownum":5,"storeName":"大悦城甜品站","addressDetail":"曲江新区慈恩西路大雁塔南广场西侧1幢10101室","pro":"Wi-Fi","provinceName":"陕西省","cityName":"西安市"}]}
reponses的属性
# 响应文本,本身是字节类型,但会以一种猜测的编码格式帮你解码成字符串
response.text
# 响应文本,字节类型的文本
response.content
# 响应的状态码
response.status_code
# 响应的头数据
response.headers
# 响应的cookie
response.cookies
# 响应字典形式的cookie
response.cookies.get_dict()
# 响应元祖形式的cookie
response.cookies.items()
# 如果请求过程中发生了重定向,会帮你记录
response.history
# 指定text是用的那种解码方式
response.encoding
response的常见问题
1编码问题
import requests
res = requests.get('http://www.baidu.com')
print(res.encoding) # 可以看见它的编码为ISO-8859-1
coding = res.apparent_encoding # 获取真实的编码方式
print(coding)
res.encoding = coding # 重新赋予解码方式
print(res.text)
2 处理字节型数据
import requests
response=requests.get('http://xxx.com')
对于小的图片,首先我们直接用res.content就行了
jpg = response.content
如果文件太大,我们不应该一下就全写进文件里,而是应该一段一段的写进去,于是我们就可以for循环res.iter_content(),\然后再一次一次写入
with open("res.png","wb") as f:
# f.write(response.content) # 比如下载视频时,如果视频100G,用response.content然后一下子写到文件中是不合理的
for line in response.iter_content():
f.write(line)
3 数据序列化
import requests
import json
response=requests.get('http://xxx.com')
# 如果要序列化我们可以这样
json_text = json.loads(response.text)
# 但是它自带的方法更好用
josn_text1 = response.json()
4 关于重定向
import requests
# 可以通过allow_redirects参数设置不让它重定向
response = requests.get('http://github.com', allow_redirects=False)