python爬虫入门

Requests入门

Requests模块简介

通过Python来模拟浏览器发送请求

  • Requests模块就是Python实现的简单易⽤的HTTP库
    目前Requests模块是最流行的。而且也是最好用的模块。其他包括urlliburllib2httplibhttplib2等模块。

安装和文档地址

利用pip安装:

pip install requests

下载代码后安装

$ git clone git://github.com/kennethreitz/requests.git
$ cd requests
$ python setup.py install

发送请求

导入 Requests 模块:

import requests

尝试获取某个网页

response = requests.get('https://www.cnblogs.com/')

打印出返回的文本的内容

response.text

在浏览器上打开这个网址, 右键选择“查看源代码”,打印出来的是一模一样(如果没有反爬或者网站是静态网站)。

  • 这样的功能urllib也是可以实现:
import urllib.request
url = 'https://www.sogou.com/'
response = urllib.request.urlopen(url)
print(response.read().decode('utf-8'))

相对于麻烦程度,推荐使用requests。

requests 除了可以发送GET请求,还可发送POST请求

response = requests.post('http://httpbin.org/post', data = {'key':'value'})

传递URL参数

为 URL 的查询字符串(query string)传递某种数据,通过拼接字符串构造的URL。那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。
例如, httpbin.org/get?key=val。 Requests 允许你使用 params 关键字参数,以一个字典来提供这些参数。
举例来说,传递 key1=value1 和 key2=value2 到 httpbin.org/get

import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)

通过打印输出该 URL,可以看到 URL 已被正确编码:

print(r.url)
# 结果如下:
http://httpbin.org/get?key2=value2&key1=value1

拓展
还可以将一个列表作为值传入:

import requests
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.get('http://httpbin.org/get', params=payload)
print(r.url)
# 打印的结果是
http://httpbin.org/get?key1=value1&key2=value2&key2=value3

响应内容

文本响应内容
之前使用r.text来访问服务器返回给我们的内容。并没有做编码解码的事情,其实requests 会自动解码来自服务器的内容。大多数 Unicode 字符集都能被无缝地解码。请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。
使用 r.encoding 属性改变编码

# 产看编码信息
r.encoding
# 结果是
‘utf-8# 指定中文编码
r.encoding = 'gb2312' # 

电影天堂乱码案例

# 导入模块
import requests
# 电影天堂网站
url = 'https://www.dytt8.net'
# 发出请求
response = requests.get(url)
# 指定编码信息 gb2312 不指定就会出错
# response.encoding = 'gb2312'
# 查看返回信息
print(response.text)

二进制响应内容
例如对于图片信息,可以很方便的保存到文件中。对于图片,mp3,视频等数据,往往要使用二进制的方式读取。

  • 下载百度图片案例
# 导入模块
import requests
# 百度图片的网站
url = 'https://www.baidu.com/img/xinshouye_1aa82cd448e4c0aee0961ed6e290baaf.gif'
# 发出请求
response = requests.get(url)
# 查看返回信息
print(response.content)
# 保存图片到本地
with open('picture.png','wb') as fp:
    fp.write(response.content)

JSON 响应内容
Json数据也是爬虫经常见到的数据格式,Requests 中也有一个内置的 JSON 解码器
r.json()
需要注意的是,成功调用 r.json() 并不意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象。这种 JSON 会被解码返回。要检查请求是否成功,请使用 r.raise_for_status() 或者检查 r.status_code 是否和你的期望相同。

  • 抓取Github中的JSON文件
# 导入模块
import requests
# github网址
url = 'https://github.com/timeline.json'
# 发送请求
response = requests.get(url)
# 查看响应数据
print(response.json()) # 注意有括号

结果:

定制请求头

添加请求头
既然浏览器有请求头的发送,那么我们的程序自然也应该加上。在Requests中我们通过 headers 参数添加请求头信息。

  • 访问百度首页搜索
# 导入模块
import requests
# 百度搜索
url = 'https://www.baidu.com/s?wd=scrapy'
# 指定请求
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36'
}
# 发送请求
response = requests.get(url, headers=headers)
# 返回响应信息
print(response.text)

注意:我们只是加上了User-Agent信息就可以正常访问了,但是浏览器是发送了比我们更多的信息的。如果遇到加上请求头User-Agent信息也不成功的网站,可以尝试添加其他请求头信息。

POST请求

POST请求主要用来提交表单数据,然后服务器根据表单数据进行分析,再决定返回什么样的数据给客户端。
Form表单提交数据

Content-Type:application/x-www-form-urlencoded

在Requests中发送POST请求也是比较容易的操作,要实现这个,只需简单地传递一个字典给data参数。你的数据字典在发出请求时会自动编码为表单形式:

payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload) 

以JSON形式提交数据

Content-Type:application/json

很多时候你想要发送的数据并非Form表单形式的。有时候数据可能是JSON格式的,对于这种格式requests也是很简单。

import json
import requests
url = 'https://xxxxx'
data = {
    'key': 'value'
}
# 传递JSON数据
r = requests.post(url, data=json.dumps(data))
# 也可以这样传递
# r = requests.post(url, json=data) 
print(r.text)

响应状态码

响应状态码可以很方便的查看我们的响应状态,我们可以检测响应状态码:

r = requests.get('http://httpbin.org/get')
r.status_code # 200

如果发送了一个错误请求(一个 4XX 客户端错误,或者 5XX 服务器错误响应),我们可以通过 response.raise_for_status()来抛出异常:

bad_r = requests.get('http://httpbin.org/status/404')
bad_r.status_code # 404
bad_r.raise_for_status() # 抛出异常
# 异常错误
Traceback (most recent call last):
  File "requests/models.py", line 832, in raise_for_status
	raise http_errorrequests.exceptions.HTTPError: 404 Client Error

如果例子中 r 的 status_code 是 200 ,当我们调用 raise_for_status() 时,得到的是:

r.raise_for_status() # 200
None

网站记录用户信息的方式就是通过客户端的Cookie值。例如:当我们在浏览器中保存账号和密码的同时,浏览器在我们的电脑上保存了我们的用户信息,并且在下次访问这个页面的时候就会自动的为我们加载Cookie信息。
在需要登陆的网站中,浏览器将Cookie中的信息发送出去,服务器验证Cookie信息,确认登录。

Cookie是当你访问某个站点或者特定页面的时候,留存在电脑里的一段文本,它用于跟踪记录网站访问者的相关数据信息,比如:搜索偏好、行为点击,账号,密码等内容。

通常Cookie值信息可以在浏览器中复制过来,放到headers中:

requests也提供了cookies 参数

cookies = {‘Cookie’: ‘你的Cookie值’}
r = requests.get(url, cookies=cookies)

重定向与请求历史

重定向
重定向(Redirect)就是通过各种方法将一个网络请求重新定个方向转到其它位置。可能的原因是有些网址现在已经废弃不准备再使用等。
处理重定向
默认情况下,对于我们常用的GET和POST请求等, Requests 会自动处理所有重定向。例如,Github 将所有的 HTTP 请求重定向到 HTTPS:

r = requests.get('http://github.com')
r.url # 'https://github.com/'
r.status_code # 200

如果你使用的是GET、POST等,那么你可以通过 allow_redirects 参数禁用重定向处理:

r = requests.get('http://github.com', allow_redirects=False)
r.status_code # 301

可以使用响应对象的 history 方法来追踪重定向。Response.history是一个 Response 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。

r = requests.get('http://github.com')
r.history # [<Response [301]>]

超时

有时候我们由于时间或者对方网站的原因,不想等待很长的时间,等待响应的回传,那么我们就可以加上一个时间超时参数,如果超过我们设定的时间,响应还没有返回,那么久不再等待。
你可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。建议所有的生产代码都应该使用这一参数。

requests.get('http://github.com', timeout=0.001)
# 报错结果
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>requests.exceptions.Timeout
    HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

错误与异常

遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。
1.如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。
2.若请求超时,则抛出一个 Timeout 异常。
3.若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。
所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException 。

posted @   NeverLateThanBetter  阅读(257)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示