首页Python1.请求库——urllib...

1.请求库——urllib库

urllib库是python内置的HTTP请求库,包括以下四个模块:

  • request:HTTP请求模块,用于模拟请求的发送;
  • error:异常处理模块,如果请求出现异常,会捕获异常;
  • parse:工具模块,提供了诸如拆分、解析等许多URL的处理方法;
  • robotparse:用于识别网站的robots.txt文件,从而判断哪些网站可以爬取,哪些网站不可爬取。

详细内容可查询官方文档

1.发送HTTP请求(request模块):

request 模块定义了适用于在各种复杂情况下打开 URL(主要为 HTTP)的函数和类 — 例如基本认证、摘要认证、重定向、cookies 及其它功能。

1.1 request模块中的urlopen方法

利用request模块中的urlopen方法可以模拟浏览器发起最基本的需求,完成对简单网页的GET请求抓取。
该方法返回的是HTTPResponse类型对象,包含read、readinto、getheader、getheaders、filneo等方法,以及msg、version、status、reason、debuglevel、closed等属性。

import urllib.request

response = urllib.request.urlopen('https://www.python.org')
print(type(response)) # 查看响应类型,为HTTPResponse类型对象
print('-'*10)
print(response.status)# 调用status属性,得到响应结果的状态码
print('-'*10)
print(response.getheaders()) # getheader()方法,得到响应的头信息
print('-'*10)
# python.org 网站已在 meta 标签中指明,采用的是 utf-8 编码,因此这里将用同样的格式对字节串进行解码。
print(response.read(100).decode('utf-8')) # 调用read()方法,得到响应的网页内容

运行结果如下:

<class 'http.client.HTTPResponse'>
----------
200
----------
[('Connection', 'close'), ('Content-Length', '50727'), ('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur, 1.1 varnish, 1.1 varnish'), ('Accept-Ranges', 'bytes'), ('Date', 'Tue, 19 Apr 2022 14:13:52 GMT'), ('Age', '2372'), ('X-Served-By', 'cache-iad-kcgs7200036-IAD, cache-hkg17923-HKG'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '11, 3940'), ('X-Timer', 'S1650377632.096333,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]
----------
<!doctype html>
<!--[if lt IE 7]>   <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9">   <![endif]-->
<!-

更多参数如下所示:

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

  • data参数:

data参数必须是一个对象,用于给出要发送到服务器的附加数据,若不需要发送数据则为None。
如果传递了该参数,那么请求方式就不再是GET,而是POST。
添加该data参数时,需要将其转换为字节流格式。

import urllib.request
import urllib.parse

# 方式1:bytes()方法第一个参数为str类型,第二个参数为指定编码格式
# data = bytes(urllib.parse.urlencode({'name':'xiaoming'}) , encoding='utf-8')
# 方式2
data = urllib.parse.urlencode({'name': 'xiaoming'}).encode('ascii')

response = urllib.request.urlopen('https://www.httpbin.org/post' , data=data)
print(response.read().decode('utf-8'))

运行结果如下:
可以看出传递的参数出现在了form字段中,表明是以POST方式传输数据,模拟表单提交。

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "name": "xiaoming"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "13", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python-urllib/3.6", 
    "X-Amzn-Trace-Id": "Root=1-625ec004-7bd3c64170f003245a8c59ed"
  }, 
  "json": null, 
  "origin": "101.86.213.228", 
  "url": "https://www.httpbin.org/post"
}
  • timeout参数:

timeout参数为可选参数,用于指定阻塞操作(如连接尝试)的超时时间,单位为秒,如果请求超过了设置的时间还没得到相应,就会抛出异常。
如未指定,将使用全局默认超时参数。本参数实际仅对 HTTP、HTTPS 和 FTP 连接有效。

  • context参数:

context参数必须是一个ssl.SSLContext实例,用于描述各种 SSL 参数。更多详情请参阅HTTPSConnection

  • cafile参数和capath参数:

cafile 和 capath 为可选参数,用于为 HTTPS 请求指定一组受信 CA 证书。cafile 应指向包含CA 证书的单个文件, capath 则应指向哈希证书文件的目录。更多信息可参阅ssl.SSLContext.load_verify_locations()

  • cadefault参数:

cadefault参数已弃用,可忽略。

TIPS:
如若出现ModuleNotFoundError: No module named 'urllib.request'; 'urllib' is not a package问题,可能是因为重名导致urllib包引用无效:
(1)正在import urllib的文件命名就是urllib.py
(2)正在使用的文件的文件夹目录下有一个叫urllib.py的文件,
导致你import urllib实际上导入的是当前目录下的urllib.py文件,而不是库里的urllib。

1.2 Request类

1.2.1 基础用法

urlopen方法可以发起最基本的请求,往往请求需要加入Headers等信息,此时就需要利用Request类来构建请求。构造方法如下:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

  • url参数:必传参数,用于请求的URL。
  • data参数:对于 HTTP POST 请求方法而言,在用作 data 参数之前,应将其编码为字节串。 可以使用 urllib.parse.urlencode() 函数映射对象或二元组序列,返回一个该编码格式的 ASCII 字符串。。
  • headers参数:headers 应为字典对象,视同于用每个键和值作为参数去调用 add_header()。 通常用于 User-Agent 头部数据的“伪装” ,浏览器用这些头部数据标识自己——某些 HTTP 服务器只允许来自普通浏览器的请求,而不接受来自脚本的请求。例如,Mozilla Firefox 可能将自己标识为 “Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11″,而 urllib 的默认用户代理字符串则是 “Python-urllib/2.6” (在 Python 2.6 上)。
  • origin_req_host参数:是用户发起初始请求的主机名或 IP 地址。
  • unverifiable参数:标示出请求是否无法验证,默认值为 False 。所谓无法验证的请求,是指用户没有机会对请求的 URL 做验证。例如,如果请求是针对 HTML 文档中的图像,用户没有机会去许可能自动读取图像,则本属性应为 True。
  • method参数:为字符串格式,标示要采用的 HTTP 请求方法(例如 ‘HEAD’ )。如果给出本参数,其值会存储在 method 属性中,并由 get_method() 使用。如果 data 为None 则默认值为 GET ,否则为 POST。子类可以设置 method 属性来标示不同的默认请求方法。

下面构造一个Request类,headers中指定User-Agent和Host,data参数将字典处理为字节流格式,同时指定method参数为Post,代码如下所示:

import urllib.request
import urllib.parse

url = 'https://www.httpbin.org/post'
headers = {'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' , 'Host':'www.httpbin.org'}
data = urllib.parse.urlencode({'name':'xiaoming'}).encode('ascii')
req = urllib.request.Request(url , data=data ,headers=headers , method='POST')
response = urllib.request.urlopen(req)
print(response.status)
print('-'*10)
print(response.read().decode('utf-8'))

运行结果如下:可以看到,成果设置了headers、data、method参数。

200
----------
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "name": "xiaoming"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "13", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)", 
    "X-Amzn-Trace-Id": "Root=1-625f7d57-7f192f1c439322f23e0bc99e"
  }, 
  "json": null, 
  "origin": "101.86.213.228", 
  "url": "https://www.httpbin.org/post"
}

在data参数中提到可以调用add_header(key, val)添加headers,代码如下所示:

import urllib.request
import urllib.parse

url = 'https://www.httpbin.org/post'
data = urllib.parse.urlencode({'name':'xiaoming'}).encode('ascii')
req = urllib.request.Request(url , data=data , method='POST')
# 调用add_header()方法添加headers
req.add_header('User-Agent' , 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')

response = urllib.request.urlopen(req)
print(response.status)
print('-'*10)
print(response.read().decode('utf-8'))

1.2.2 高级用法

如若需要设置Cookie和代理等操作,就需要使用urllib.request模块中的BaseHandler类,这是所有已注册 handler 的基类。

  • HTTPDefaultErrorHandler——为 HTTP 错误响应定义的默认 handler,所有响应都会转为 HTTPError 异常。
  • HTTPRedirectHandler——一个用于处理重定向的类。
  • HTTPCookieProcessor(cookiejar=None)——用于处理 HTTP Cookies 的类。
  • HTTPPasswordMgr——用于管理密码,维护 (realm, uri) -> (user, password) 映射数据库,即用户名密码的对照表。
  • HTTPPasswordMgrWithDefaultRealm()——该类将创建一个密码管理对象,用来保存 HTTP 请求相关的用户名和密码,主要应用两个场景:验证代理授权的用户名和密码 (ProxyBasicAuthHandler())、验证Web客户端的的用户名和密码 (HTTPBasicAuthHandler())。
  • HTTPBasicAuthHandler(password_mgr=None)——用于处理与远程主机的身份验证。如果一个链接在打开时需要认证,可以使用该类解决认证问题。
  • ProxyHandler(proxies=None)——用于设置代理服务的类。若给出了 proxies,则其必须是一个将协议名称映射为代理 URL 的字典对象。

具体使用场景如下:

  • 验证:

在访问某些网站时,会弹出验证窗口,表明该网站启用了基本身份认证(HTTP Basic Access Authentication)。作为一种网站登录验证方式,需要在请求网站时提供用户名和密码形式的身份凭证。

import urllib.request

# 首先实例化一个HTTPBasicAuthHandler对象auth_handler,其参数是HTTPPasswordMgrWithDefaultRealm对象,利用add_password()方法添加用户名和密码。
# 然后将建立的auth_handler类当做参数传入build_opener()方法,构建一个Opener,该Opener在发送请求时就相当于已经验证成功了。
# 最后利用Opener类中的open()方法打开url,获取验证成功后的页面源码。

url='https://ssr3.scrape.center/'
# 用户名
username = 'admin'
# 密码
password = 'admin'

# 构建一个密码管理对象,用来保存需要处理的用户名和密码
p = urllib.request.HTTPPasswordMgrWithDefaultRealm()
# 添加账户信息,第一个参数realm是与远程服务器相关的域信息,一般都是写None,后面三个参数分别是 Web服务器、用户名、密码
p.add_password(None , url , username , password)
# 构建一个HTTP基础用户名/密码验证的HTTPBasicAuthHandler处理器对象,参数是创建的密码管理对象
auth_handler = urllib.request.HTTPBasicAuthHandler(p)
# 通过 build_opener()方法使用这些代理Handler对象,创建自定义opener对象
opener = urllib.request.build_opener(auth_handler)

try:
    # 使用open()方法打开url,获取验证成功后的页面源码。
    req = opener.open(url)
    html = req.read().decode('utf-8')
    print(html)
except URLError as e:
    print(e,reason)
  • 代理:

如若需要添加代理,就需要使用ProxyHandler类。

import urllib.request
import urllib.error

# 使用ProxyHandler构建代理,参数为字典类型,键名为协议类型,键值为代理链接,可以添加多个代理
proxy_handler = urllib.request.ProxyHandler({
    'http':'代理链接',
    'https':'代理链接'
})
# 通过 build_opener()方法创建自定义opener对象
opener = urllib.request.build_opener(proxy_handler)

try:
    # 使用open()方法打开url
    response = opener.open('https://www.baidu.com')
    print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
    print(e.reason)
  • Cookie:

获取网站Cookie代码如下:

import http.cookiejar
import urllib.request

# 声明一个CookieJar对象
cookie = http.cookiejar.CookieJar()
# 利用HTTPCookieProcessor构建一个Handler
handler = urllib.request.HTTPCookieProcessor(cookie)
# 使用build_opener方法构建Opener
opener = urllib.request.build_opener(handler)
# 使用open()方法打开url
response = opener.open('https://www.baidu.com')
print(cookie)
print('-'*10)
# 输出每个Cookie条目的名称和值
for item in cookie:
    print(item.name + "=" + item.value)

运行结果如下:

<CookieJar[<Cookie BAIDUID=0241D6834CF8D724F28624CAB16BC260:FG=1 for .baidu.com/>, <Cookie BIDUPSID=0241D6834CF8D7244319925EDA945300 for .baidu.com/>, <Cookie PSTM=1650430523 for .baidu.com/>, <Cookie BD_NOT_HTTPS=1 for www.baidu.com/>]>
----------
BAIDUID=0241D6834CF8D724F28624CAB16BC260:FG=1
BIDUPSID=0241D6834CF8D7244319925EDA945300
PSTM=1650430523
BD_NOT_HTTPS=1

可以获取网站Cookie,那么就可以将获取的cookie输出为文件格式,保存在本地,代码如下:

import http.cookiejar
import urllib.request

filename = 'cookie.txt'

# 声明一个MozillaCookieJar对象,它是CookieJar的子类,用来处理跟Cookie和文件相关的事件,例如读取和保存Cookie
cookie = http.cookiejar.MozillaCookieJar(filename)
# 利用HTTPCookieProcessor构建一个Handler
handler = urllib.request.HTTPCookieProcessor(cookie)
# 使用build_opener方法构建Opener
opener = urllib.request.build_opener(handler)
# 使用open()方法打开url
response = opener.open('https://www.baidu.com')
# 将cookie保存为Mozilla型浏览器的Cookie格式
cookie.save(ignore_discard=True , ignore_expires=True)

运行完可以看到文件夹内生成了cookie.txt文件,打开文件可以看到如下内容:

# Netscape HTTP Cookie File
# http://curl.haxx.se/rfc/cookie_spec.html
# This is a generated file!  Do not edit.

.baidu.com	TRUE	/	FALSE	1681970972	BAIDUID	4D3A52A9EFF7A3B0E3047225C2EC6890:FG=1
.baidu.com	TRUE	/	FALSE	3797918619	BIDUPSID	4D3A52A9EFF7A3B0890C0834CFD9CD2A
.baidu.com	TRUE	/	FALSE	3797918619	PSTM	1650434972
www.baidu.com	FALSE	/	FALSE	1650435272	BD_NOT_HTTPS	1

生成了cookie文件,可以使用如下代码读取cookie,并构建请求。

import http.cookiejar
import urllib.request

cookie = http.cookiejar.MozillaCookieJar()
# 使用load()方法读取本地cookie文件
cookie.load('cookie.txt' , ignore_expires=True , ignore_discard=True)
# 利用HTTPCookieProcessor构建一个Handler
handler = urllib.request.HTTPCookieProcessor(cookie)
# 使用build_opener方法构建Opener
opener = urllib.request.build_opener(handler)
# 使用open()方法打开url
response = opener.open('https://www.baidu.com')
print(response.read().decode('utf-8'))

2.处理异常(error模块):

urllib.error 模块为 urllib.request 所引发的异常定义了异常类。

  • URLError

URLError是error模块的基类。
具有reason属性,用于获取错误的原因。

import urllib.request , urllib.error

# 请求一个不存在的页面,返回请求结果
try:
    response = urllib.request.urlopen('https://www.baidu.com/404')
except urllib.error.URLError as e:
    print(e.reason)

运行结果如下:

Not Found
  • HTTPError

HTTPError是URLError的子类,专门用于处理HTTP请求错误,有三个属性:code(返回HTTP状态码)、reason(返回错误原因)、headers(返回请求头)。

import urllib.request , urllib.error

try:
    response = urllib.request.urlopen('https://www.baidu.com/404')
except urllib.error.HTTPError as e:
    print(e.reason)
    print('---------')
    print(e.code)
    print('---------')
    print(e.headers)

运行结果如下:

Not Found
---------
404
---------
Content-Length: 201
Content-Type: text/html; charset=iso-8859-1
Date: Wed, 20 Apr 2022 06:37:18 GMT
Server: Apache
Connection: close

TIPS:
因为HTTPError为URLError的子类,所以会优先捕捉子类HTTPError的错误,然后再捕捉父类URLError的错误,可以使用else语句处理正常的异常处理逻辑。

import urllib.request , urllib.error

try:
    response = urllib.request.urlopen('https://www.baidu.com/404')
# 先捕获HTTPError,获取错误原因、状态码、请求头
except urllib.error.HTTPError as e:
    print(e.reason , e.code , e.headers)
# 如果不是HTTPError,则会捕获URLError,获取错误原因
except urllib.error.URLError as e:
    print(e.reason)
else:
    print('请求成功!')

3.url解析(parse模块):

该模块定义了处理URL的标准化接口,用于实现URL的抽取、合并以及转换等操作。支持以下协议的URL处理:file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss

3.1 URL解析

3.1.1 urlparse

一个标准的URL都会符合如下规则:scheme://netloc/path;params?query#fragment,使用urlparse()方法可以将URL拆分开来。
其API用法为:urlparse(urlstring, scheme='', allow_fragments=True)

  • urlstring:必选参数,为待解析的URL。
import urllib.parse

urlstring = 'https://www.baidu.com/index.html;user?id=5#top'

result = urllib.parse.urlparse(urlstring)
print(type(result))
print(result)

运行结果如下:
可以看出,返回结果为ParseResult类型的对象,包含scheme、etloc、path、params、query、fragment六部分内容。

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='top')

返回的ParseResult类型对象实际上是一个元祖,可以通过属性名获取单个内容,也可以使用索引获取。

import urllib.parse

urlstring = 'https://www.baidu.com/index.html;user?id=5#top'

result = urllib.parse.urlparse(urlstring)
print(type(result))
print(result)
print('-----------')
print(result.scheme , result[0])

运行结果如下:

<class 'urllib.parse.ParseResult'>
ParseResult(scheme='https', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='top')
-----------
https https
  • scheme:默认协议,如果待解析的URL中没有协议信息,就会将该参数值作为默认协议。需注意的是,只有在待解析的URL中不包含协议信息时才生效,如果待解析URL中包含有协议信息,则无效,结果放回解析出的协议信息。
import urllib.parse

urlstring = 'www.baidu.com/index.html;user?id=5#top'

result = urllib.parse.urlparse(urlstring , scheme='https')
print(result)

运行结果如下:

ParseResult(scheme='https', netloc='', path='www.baidu.com/index.html', params='user', query='id=5', fragment='top')
  • allow_fragments:用于指定是否忽略fragment,默认为True。设置为False时,fragment部分会被忽略,结果不返回待解析URL中的fragments信息。
import urllib.parse

urlstring = 'www.baidu.com/index.html;user?id=5#top'

result = urllib.parse.urlparse(urlstring , allow_fragments=False)
print(result)

运行结果如下:

ParseResult(scheme='', netloc='', path='www.baidu.com/index.html', params='user', query='id=5#top', fragment='')

3.1.2 urlunparse

与urlparse方法相对应,urlunparse方法用于构造URL。
该方法接收的参数为一个可迭代对象(列表、元祖等),其长度必须为6,否则会抛出参数数量不足或者过多的错误信息。

import urllib.parse

data = ['https' , 'www.baidu.com' , 'index.html' , 'user' , 'id=5' , 'top']
result = urllib.parse.urlunparse(data)
print(result)

运行结果如下:

https://www.baidu.com/index.html;user?id=5#top

3.1.3 parse_qs

parse_qs方法可以将一串GET请求参数转换为字典格式。

import urllib.parse

data = 'name=xiaoming&age=18'
result = urllib.parse.parse_qs(data)
print(result)

运行结果如下:

{'name': ['xiaoming'], 'age': ['18']}

3.1.4 parse_qsl

parse_qsl方法可以将一串GET请求参数转换为由元祖组成的列表。

import urllib.parse

data = 'name=xiaoming&age=18'
result = urllib.parse.parse_qsl(data)
print(result)

运行结果如下:

[('name', 'xiaoming'), ('age', '18')]

3.1.5 urlsplit

与urlparse方法类似,只不过urlsplit方法不单独解析返回params部分,会被合并到path部分,因此只返回5部分结果。

import urllib.parse

urlstring = 'https://www.baidu.com/index.html;user?id=5#top'

result = urllib.parse.urlsplit(urlstring)
print(type(result))
print(result)

运行结果如下:

<class 'urllib.parse.SplitResult'>
SplitResult(scheme='https', netloc='www.baidu.com', path='/index.html;user', query='id=5', fragment='top')

3.1.6 urlunsplit

与urlunparse方法类似,用于构造URL,接收的参数也为一个可迭代对象,不同的是urlunsplit方法接收的参数长度必须为5。

import urllib.parse

data = ['https' , 'www.baidu.com' , 'index.html' ,  'id=5' , 'top']
result = urllib.parse.urlunsplit(data)
print(result)

运行结果如下:

https://www.baidu.com/index.html?id=5#top

3.1.7 urljoin

urlunparse和urlunsplit方法都可以完成URL的合并,但是前提是传入的参数必须是特定长度的对象,URL中的每一部分要明确分开。
urljoin方法也可以生产链接,,该方法第一个参数为base_url基础链接,第二个参数为新链接。
urljoin方法会分析base_url基础链接中的scheme、netloc和path三部分内容,如果新链接中不存在此三项,就进行自动补齐;如果新链接中存在此三项,就使用新链接中的内容,base_url不起作用。
通过urljoin方法可以很方便的实现链接的解析、拼合与生成。

import urllib.parse

print(urllib.parse.urljoin('https://www.baidu.com' , 'index.html'))
print('------------')
print(urllib.parse.urljoin('https://www.baidu.com' , '?id=5#top'))
print('------------')
print(urllib.parse.urljoin('https://www.baidu.com/index.html' , 'https://www.baidu.com'))
print('------------')
print(urllib.parse.urljoin('https://www.baidu.com/index.html' , 'https://www.baidu.com/about.html'))

运行结果如下:

https://www.baidu.com/index.html
------------
https://www.baidu.com?id=5#top
------------
https://www.baidu.com
------------
https://www.baidu.com/about.html

3.2 URL转码

3.2.1 urlencode

urlencode方法可以将字典数据转化为URL的GET请求的参数。
该方法在构造GET请求参数的时候非常有用,有时为了方便地构造参数,会事先使用字典将参数表示出来,在后续将字典转化为URL参数的时候,只需调用该方法即可。

import urllib.parse

params = {
    'name':'xiaoming',
    'age':'18'
}

base_url = 'https://www.baidu.com?'
url = base_url + urllib.parse.urlencode(params)
print(url)

运行结果如下:

https://www.baidu.com?name=xiaoming&age=18

3.2.2 quote

该方法用于将内容转换为URL编码格式。
当URL中带有中文参数时,有可能会导致乱码问题,此时可使用quote方法将中文字符转化为URL编码格式。

import urllib.parse

keyword = '编程'
base_url = 'https://www.baidu.com/s?wd='
url = base_url + urllib.parse.quote(keyword)
print(url)

运行结果如下:

https://www.baidu.com/s?wd=%E7%BC%96%E7%A8%8B

3.2.3 unquote

与quote相对应,unquote方法用于对URL进行解码操作。

import urllib.parse

url = 'https://www.baidu.com/s?wd=%E7%BC%96%E7%A8%8B'
print(urllib.parse.unquote(url))

运行结果如下:

https://www.baidu.com/s?wd=编程

4.分析Robots协议(robotparse模块):

robotparse模块用于分析网站的Robots协议,该协议一般放置在网站根目录下一个名为robots.txt文本文件中。
该模块提供了一个RobotFileParser类,根据网站的Robots协议判断某个爬虫是否有权限爬取该网页。
RobotFileParser类包含如下方法:

  • set_url:用于设置robots.txt文件的链接。如果在擦黄建RobotFileParser对象时传入了链接,就不再需要该方法设置。
  • read:用于读取robots.txt文件并进行分析。
  • parse:用于解析robots.txt文件,传入的参数为robots.txt文件中某些行的内容,它会按照robots.txt的语法规则分析传入的内容。
  • can_fetch:第一个参数为User-Agent,第二个参数为要爬取的URL,通过返回结果判断由User-Agent指示的搜索引擎能否爬取该URL。
  • modified:可以将当前时间设置为上次抓取和分析robots.txt文件的时间,对长时间分析和爬取的搜索爬虫很有帮助。
import urllib.robotparser

rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://www.baidu.com/robots.txt')
rp.read()
print(rp.can_fetch('Baiduspider' , 'https://www.baidu.com'))
print(rp.can_fetch('Googlebot' , 'https://www.baidu.com'))
print('-------------')
print(rp.can_fetch('Baiduspider' , 'https://www.baidu.com/homepage/'))
print(rp.can_fetch('Googlebot' , 'https://www.baidu.com/homepage/'))

运行结果如下:

True
True
-------------
True
False

Reference:
《Python3网络爬虫开发实战》

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments