网络爬虫的限制

  • 来源审查:检查来访HTTP协议头的 User-Agent 域,只响应浏览器或友好爬虫的访问

  • 发布公告:Robots 协议(网络爬虫排除标准),告知所有爬虫网站的爬取策略,要求爬虫遵守

    Robots 协议,一般放置在网站根目录下的robots.txt文件。

    在爬虫之前,需要识别robots.txt,再进行内容爬取

    原则:类人行为可不参考Robots协议

urllib 库

Python3 的 urllib 库,无需安装,用于操作网页的URL,并对网页的内容进行抓取处理。

该包包含四个模块:

  • urllib.request:打开和读取URL
  • urllib.error:包含 urllib.request 抛出的异常
  • urllib.parse:解析URL
  • urllib.robotparser:解析 robots.txt 文件

urllib.parse

该库能够对 URL 进行解析,我们常用其来封装 请求中需要传输的数据,

首先对其进行引入:

1
import urllib.parse

当我们需要发送GET请求时,有时候会需要在URL中携带请求参数;又或者是当需要发送POST请求时,请求中需要携带表单数据。而 urllib.parse.urlencode() 能够将字典或元组数据转换为URL请求中可携带的数据。例如:

1
2
urllib.parse.urlencode({"任务":"go shopping"})
# 返回字符串(URL请求参数的格式):%E4%BB%BB%E5%8A%A1=go+shopping

urllib.request

urllib.request 定义了打开URL的方法及相关的类,包含授权验证、重定向、浏览器 cookies 等,可通过它模拟浏览器的一个请求发起过程

首先对其进行引入:

1
import urllib.request

(一)发送URL请求

urllib.request.urlopen(url, data=None, .....) 其中,参数 data 为发送到服务器的其他数据对象。

上述方法的返回值,可以调用 read() 以获取响应正文,或者调用 getcode() 获取状态码

1
2
3
4
5
6
7
8
9
10
11
myURL = urllib.request.urlopen("https://www.joydee.top/")
print(type(response)) # <class 'http.client.HTTPResponse'>
print(response.getcode()) # 网页正常,返回200
print(response.read().decode("utf-8"))
# 使用UTF-8解码方式,获取响应正文(网页的HTML代码)
'''
<!DOCTYPE html><!--STATUS OK-->
<html><head><meta http-equiv="Content-Type" content="text/html;charset=utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
..........
'''

上述代码相当于发送一个GET请求,下面方法是发送POST请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
data = bytes(urllib.parse.urlencode({"任务":"go shopping"}), encoding="utf-8")
# 先将传入的字典转换为URL参数格式的字符串,再创建个与之对应的bytes字节数组
response = urllib.request.urlopen("http://httpbin.org/post", data=data)
# data 需要传入表单数据的字节数组
print(response.read().decode("utf-8"))
# 打印响应正文:
'''
{
"args": {},
"data": "",
"files": {},
"form": {
"\u4efb\u52a1": "go shopping"
},
"headers": {
"Accept-Encoding": "identity",
"Content-Length": "30",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Python-urllib/3.8",
"X-Amzn-Trace-Id": "Root=1-****-436******ee399021********"
},
"json": null,
"origin": "?.?.?.?",
"url": "http://httpbin.org/post"
}
'''

(二)模拟HTTP请求头

为了符合请求网站对请求的来源审查,需要在HTTP请求中的请求头中模板进行编辑。

代码举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
url = "https://www.douban.com/"
data = bytes(urllib.parse.urlencode({"name": "Luffy"}), encoding="utf-8")

#模拟HTTP请求头
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
} # 头部信息
req = urllib.request.Request(url=url, data=data, headers=headers, method="POST")
# 为保证顺利访问,url与headers参数是必需项,其中headers传入的是字典类型

response = urllib.request.urlopen(req)
print(response.read().decode("utf-8"))