网络爬虫笔记-requests库

网络爬虫笔记-requests库

一、requests库的安装

首先,打开Anaconda的命令提示符界面;然后输入下面的代码即可安装requests库。

pip install requests

二、get请求

2.1 什么是get请求

当我们在浏览器中输入一个网址(网址也可以叫做URL)并回车,这便发起了一个get请求。get请求的参数会直接出现在我们输入的URL网址中。

2.2 一个简单的get请求实例

import requests
test_url="http://httpbin.org/get"#这是get请求的测试网址
r = requests.get(test_url)#向服务器发起get请求
print(r.text)#将网页呈现的内容以文本的形式输出

输出结果

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.27.1", 
    "X-Amzn-Trace-Id": "Root=1-63319da6-1be94fd22ef00911623608ad"
  }, 
  "origin": "183.195.56.89", 
  "url": "http://httpbin.org/get"
}

2.3 带参数的get请求

假如我们要在上述的测试地址中加入两个参数,将地址写成“http://httpbin.org/get?name=MacroSpider&age=1” ,我们再来看一下访问该地址的输出:

import requests
test_url="http://httpbin.org/get?name=MacroSpider&age=1"
r = requests.get(test_url)#向服务器发起get请求
print(r.text)#输出服务器返回的文本

输出结果

{
  "args": {
    "age": "1", 
    "name": "MacroSpider"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.27.1", 
    "X-Amzn-Trace-Id": "Root=1-63319f01-4ea41d4e411b438b209ccd80"
  }, 
  "origin": "183.195.56.89", 
  "url": "http://httpbin.org/get?name=MacroSpider&age=1"
}

与未加参数的输出内容对比,在args处,多了我们输入的参数,说明参数输入成功。其实我们也可以通过下面的方法来输入get参数

import requests
test_url="http://httpbin.org/get"
data = {"name":"MacroSpider","age":1}
r = requests.get(test_url,params=data)#向服务器发起get请求
print(r.text)#输出服务器返回的文本

我们可以发现,这两种方法都可以发送带参数的get请求,第二种方法更加的简介和方便操作。 上述网站返回的文本是一个字典格式的文本,针对字典格式的文本,我们可以用json方法,将其转化为字典,以此来方面数据的提取。

rdic = r.json()
print(type(rdic),rdic["args"])

输出结果

<class 'dict'> {'args': {'age': '1', 'name': 'MacroSpider'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.27.1', 'X-Amzn-Trace-Id': 'Root=1-63319fb9-106024135b7e500b07940589'}, 'origin': '183.195.56.89', 'url': 'http://httpbin.org/get?name=MacroSpider&age=1'} {'age': '1', 'name': 'MacroSpider'}

通过json方法,我们将文本格式的数据转化成了字典格式,这样后面通过字典的key即可获取所需数据

2.4 抓取知乎数据

import requests
import re
headers = {"user-agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}
#headers中的user-agent字段的目的是设置请求头,将该请求伪装成是浏览器的请求,有些网站如果不伪装会无法抓取数据
test_url = "https://www.zhihu.com/explore"
r = requests.get(test_url,headers=headers)#向服务器发起get请求
titles = re.findall(r"question\/[0-9]+\"\>(.*?)\</a\>",r.text)#利用正则表达式解析网页返回的文本,并获取目标数据
print(titles)

输出结果

['湖南两人穿「和服」餐馆就餐,阿姨劝阻遭怼,如何看待此事?', '为什么有些老顾客吃着吃着就不再来照顾生意了?', '王毅阐述「六点主张」,会后许多国家代表等候与中方握手交流,表示对倡议的支持与认可,如何看待这一细节?', '如何评价电影《隐入尘烟》票房过一亿突遭下架?', '台媒称「佩洛西专机降落松山机场」,有哪些信息值得关注?', '布林肯称「是否访问台湾将由佩洛西自行决定」,推特网友嘲讽布林肯逻辑,如何评价他的表态?', '华春莹发了一组中美对比图「破坏与建设」,形成了怎样的对比?释放了哪些信号?', '俄外长称西方国家向乌克兰提供了武器、情报,实质上已经参加乌克兰冲突,如何看待这一表态?']

上述抓取的是下图红色方框内的内容

2.5 抓取二进制数据

图片、音频和视屏等都是二进制数据,不能直接通过文本获取,需要抓取这些数据的二进制代码,并写进文件中。

import requests
test_url = "https://static.zhihu.com/heifetz/assets/loginBackgroundImg.2c81e205.png"#知乎图片地址
r = requests.get(test_url)#向服务器发起get请求
with open("zhihu.png","wb") as f:#写入二进制数据
    f.write(r.content)

这里用到了open函数,第一个参数代表文件名,第二参数代表以二进制形式打开。r.content可以获取二进制信息。
运行上述代码即可在代码的文件夹中生成一个名称为“zhihu”的图片,即下面的图片

3 post请求

post请求大多在表单提交时发起。例如登录表单,输入用户名和密码,点击登录。其数据通常以表单的形式提交,而不在URL中体现。

import requests
test_url="http://httpbin.org/post"#与前面的get测试网址相比,这里将get变成了post
data = {"name":"MacroSpider","age":1}
r = requests.post(test_url,data=data)#get是用params,而post是用data
print(r.text)

输出结果

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "1", 
    "name": "MacroSpider"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Content-Length": "22", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.27.1", 
    "X-Amzn-Trace-Id": "Root=1-633455ac-0656f7c4387ef4a22bc689c2"
  }, 
  "json": null, 
  "origin": "183.195.59.65", 
  "url": "http://httpbin.org/post"
}

从返回结果来看,我们传输的数据,成功的出现在了form部分里面,说明post请求成功。

4 响应

向网站发送请求后,会得到来自网站的数据,这些数据包括状态码、响应头、cookies等

import requests
headers = {"user-agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"}
r = requests.get("http://www.jianshu.com",headers=headers)
print(type(r.status_code),r.status_code)#获取请求状态,可以知道是否成功访问网页
print(type(r.headers),r.headers)#获取请求头
print(type(r.cookies),r.cookies)#获取cookies,cookies里面包含你的登录信息,每次向网页发起请求时,将cookies作为参数传递给服务器,以便服务器识别信息
print(type(r.url),r.url)#获取url
print(type(r.history),r.history)

输出结果

<class 'int'> 200
<class 'requests.structures.CaseInsensitiveDict'> {'Date': 'Wed, 28 Sep 2022 14:21:51 GMT', 'Content-Type': 'text/html; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'X-Frame-Options': 'SAMEORIGIN', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'ETag': 'W/"52e6922c5806bc60b810a4e340d2621e"', 'Cache-Control': 'max-age=0, private, must-revalidate', 'Set-Cookie': 'locale=zh-CN; path=/', 'X-Request-Id': 'f2e8ef8d-f7f2-4484-bd54-e7c5e737f002', 'X-Runtime': '0.006302', 'Content-Encoding': 'gzip'}
<class 'requests.cookies.RequestsCookieJar'> <RequestsCookieJar[<Cookie locale=zh-CN for www.jianshu.com/>]>
<class 'str'> https://www.jianshu.com/
<class 'list'> [<Response [301]>]

5 高级用法

5.1 文件上传

文件上传需使用post方法

import requests
files = {"file":open("zhihu.png","rb")}#读取之前从知乎下载的图片
r = requests.post("http://httpbin.org/post",files=files)#附件上传用的是files参数
print(r.text)

输出结果

{
  "args": {}, 
  "data": "", 
  "files": {
    "file": "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAAt..."
  }, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate, br", 
    "Content-Length": "125904", 
    "Content-Type": "multipart/form-data; boundary=ec39a45f82cb7d150cbe9af220a06903", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.27.1", 
    "X-Amzn-Trace-Id": "Root=1-63345abc-46319ee56079b0af769d96ae"
  }, 
  "json": null, 
  "origin": "183.195.59.65", 
  "url": "http://httpbin.org/post"
}

从返回的结果来看,在files部分多出了许多数据,这正是我们上传的图片(由于输出内容较多,上面的内容省略了一部分)。文件上传需要一个单独的files字段,而不是data,form等字段。

5.2 Cookies的使用

Cookies里面保存了我们的登录信息,服务器通过Cookier来判断是哪个用户登录,从而做出相应的回应。例如有些网站需要登录之后才能访问,这时我们可以
先在网页端,登录网页。然后查看登录后Cookies信息,最后在爬取数据的时候,以请求头的形式将该Cookies值传递给服务器,这样便可以正常爬取数据了。

案例:使用Cookies维持登录状态
import requests
headers = {
    "User-Agent":"Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
    "Cookie":"_ga=GA1.2.1338053426.1661864805; cloud-..."
}
r = requests.get("https://www.zhihu.com",headers=headers)
print(r.text)

这种方式只对部分网站是有效的,有的网站通过这用方式也不能成功登录。代码中cookie需换成自己的cookies

获取登录后cookie信息(以edge浏览器为例)

1、进入知乎网页,登录你的账号;

2、在网页空白处右键,然后选择“检查”;

3、此时右侧会弹出界面,选择界面中的“网络”;

4、重新刷新一下页面(右键网页空白处,在弹出的界面中选择“刷新”);

5、此时“网络”处信息会重新刷新。然后按照下图的顺序便可得到cookie信息。

5.3 会话维持

我们通过post或get方法,每发送一次请求就相当于重新打开一次浏览器。每一次操作都是新的操作和原来的操作互不相关。他并不能像我们用浏览器浏览网页一样,只需要打开一次浏览器,然后通过点击和输入等一些操作获取网页的信息。为了达到这种效果我们就需要用到会话维持技术。

import requests
r = requests.get("http://httpbin.org/cookies")#cookie的测试网址
print(r.text)

输出结果

{
  "cookies": {}
}

上面为网页最初返回的内容。该cookies的测试网址会返回一个空的cookies,下面我们给该网站设置一个cookies

import requests
r = requests.get("http://httpbin.org/cookies/set/numbers/123456789")
print(r.text)

输出结果

{
  "cookies": {
    "numbers": "123456789"
  }
}

从返回结果来看,cookie设置成功。下面看一下不使用会话维持能否获取设置好cookies的内容。

import requests
requests.get("http://httpbin.org/cookies/set/numbers/123456789")#设置cookies
r = requests.get("http://httpbin.org/cookies")
print(r.text)

输出结果

{
  "cookies": {}
}

从运行结果来看,即便我们设置了cookies,但是当我们再次发起get请求时,还是获取不到设置的cookies,下面再看一下运用会话维持的效果;

import requests
s = requests.Session()
s.get("http://httpbin.org/cookies/set/numbers/123456789")#设置cookies
r = s.get("http://httpbin.org/cookies")
print(r.text)

输出结果

{
  "cookies": {
    "numbers": "123456789"
  }
}

从返回结果来看,通过会话维持,即便我们再次发起请求,也可以成功获取之前设置的cookies值

5.4 SSL证书验证

我们在访问国家统计局(https://data.stats.gov.cn) 数据查询网站时,浏览器或许会跳出如下提示:

这时我们用requests向该网站发起请求时,便会报错。

import requests
r = requests.get("https://data.stats.gov.cn")
print(r.status_code,r.text)

输出结果

SSLError: HTTPSConnectionPool(host='data.stats.gov.cn', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)')))

报错内容为:SSLError,这是因为该网站没有被官方CA机构认证,从而不能验证通过。此时我们可以通过设置verify的方法来规避这种认证。从而正常访问网页。

import requests
from requests.packages import urllib3
urllib3.disable_warnings()#因为我们忽略验证,系统会有警告,通过该语句可以忽略警告
r = requests.get("https://data.stats.gov.cn",verify=False)
print(r.status_code)#返回的结果为200,代表访问成功

5.5 代理设置

有些网站,在测试的时候请求几次可以正常获取内容。但当大规模爬取的时候,就会弹出验证码,甚至封禁客户端的IP,导致不能正常抓取内容。而这时就需要用代理来解决这一个问题。代理的参数为proxies

import requests 
proxies = {
"http":"http://10.10.1.10:3128", #如果代理地址需要用到用户名和密码可以这样写http://user:password@10.10.1.10:3128/
"https":"http//10.10.1.10:1080"
}
requests.get("https://www.taobao.com",proxies=proxies) 

上述的代码并不能有效运行,因为代理是无效的,在实际使用时可以换成自己的代理试一下。

5.6 超时设置

有时服务器反应比较慢,我们等了很长时间都没有得到响应,但系统又没有报出异常。这时我们可以通过timeout参数设置一个等待时间,如果超过这个时间没有响应,则系统会有超时提示。

import requests
r = requests.get("https://www.baidu.com",timeout=1)#设置超时时间为1秒,如果一秒内没有反应则弹出提示。
print(r.status_code)

参考书目:

《Python3网络爬虫开发实战》_崔庆才

End

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值