爬虫快速入门教程:利用urllib实现网络请求(下)

本文介绍了Python爬虫中urllib模块的异常处理,包括HTTPError和URLError的捕获,以及如何使用robots.txt解析模块来理解网站的爬虫协议,确保合规抓取。通过实例展示了如何读取和分析robots.txt,获取网站的抓取限制和建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前边我们讲了使用urllibrequest模块和parse模块来分别完成网络请求的发起和URL的正确处理。在这些过程中,我们不免会遇到一些错误,那么当错误发生时,我们应该怎么样避免程序出现我们意料之外的结果呢?其实答案与其他的场景没什么区别,那就是利用好异常捕获工具。

一、urllib中的异常模块:error

捕获异常的主要目的是在异常发生时,让程序继续执行我们设定好的动作(比如打印详细日志、将内存中的数据写入数据库、重新抓取当前网页等),而非直接终止,从而让我们的程序更加稳健。

urllib.error模块定义了在request模块调用过程中会产生的异常。

  • URLError是该模块的基类,由request产生的所有异常都可以通过它来捕获。
  • HTTPErrorURLError的子类,专门用来处理HTTP请求相关的错误,如认证失败、网页不存在等。
  • ContentTooShortError是指下载的数据量比预期小,它在我们使用urllib.request.urlretrieve()方法下载网页到本地时可能会触发,触发条件就是下载的内容长度小于headerContent-Length的取值。

我们用一个简单的例子来演示下error模块的使用。

from urllib.request import urlopen
from urllib.error import URLError, HTTPError


try:
    response = request.urlopen('https://www.baidu.com/nothing.html')
except HTTPError as e:
    print('******code*****')
    print(e.code)
    print('\n')
  
    print('******reason*****')
    print(e.reason)
    print('\n')
  
    print('******headers*****')
    print(e.headers)
    print('\n')
  
    print('******error*****')
    print(e)
    print('\n')

except error.URLError as e:
    print(e.reason)
    print(e)
  
else:
    print('看到我说明你请求成功了!')
  
finally:
    print('无论如何你都会看到我!')


输出如下:

******code*****
404


******reason*****
Not Found


******headers*****
Content-Length: 210
Content-Type: text/html; charset=iso-8859-1
Date: Wed, 01 Feb 2023 12:57:32 GMT
Server: Apache
Connection: close




******error*****
HTTP Error 404: Not Found


无论如何你都会看到我!

可以看到,我们先检查是否出现了HTTPError,然后再检查是否出现了URLError,这是因为HTTPErrorURLError的子类,包含更详细的信息,如HTTP状态码、请求头等。如果不是HTTPError那么我们再用URLError来捕获,看一下错误的原因是什么。

如果没有出现URLError,那理论上我们这次请求是成功的。

二、robotparser模块:网站可以爬取吗?

事实上,我们在抓取网页内容时,经常会忽略一些网站的提示。但是这些提示很可能是重要的。

比如一个网站提示了某个网页禁止抓取,那么这个时候我们强行抓取可能是有侵权甚至违法的风险。

又比如一个网站告知了你建议的抓取频率,但你并不遵循,那很有可能你的IP地址会被永久封禁,以后就再也不能访问该网站了。

那么我们应该如何获取并解析网站的提示呢?这就要用到robotparser模块了。

一、爬虫协议

robotparser模块用于分析网站的Robots协议,一般来说,该协议存放于站点根目录下,命名为robots.txt,比如https://www.douban.com/robots.txt就存储着豆瓣网站的Robots协议。

Robots协议又称爬虫协议、机器人协议,用于网站告诉搜索引擎和爬虫一些信息:

  • 允许抓取路径和禁止抓取路径
  • 允许哪些爬虫抓取网站内容
  • 建议抓取频率
  • 站点地图
  • ……

比如豆瓣的爬虫协议为:

User-agent: *
Disallow: /subject_search
Disallow: /amazon_search
Disallow: /search
Disallow: /group/search
Disallow: /event/search
Disallow: /celebrities/search
Disallow: /location/drama/search
Disallow: /forum/
Disallow: /new_subject
Disallow: /service/iframe
Disallow: /j/
Disallow: /link2/
Disallow: /recommend/
Disallow: /doubanapp/card
Disallow: /update/topic/
Disallow: /share/
Disallow: /people//collect
Disallow: /people/
/wish
Disallow: /people//all
Disallow: /people/
/do
Allow: /ads.txt
Sitemap: https://www.douban.com/sitemap_index.xml
Sitemap: https://www.douban.com/sitemap_updated_index.xml

# Crawl-delay: 5

User-agent: Wandoujia Spider
Disallow: /

User-agent: Mediapartners-Google
Disallow: /subject_search
Disallow: /amazon_search
Disallow: /search
Disallow: /group/search
Disallow: /event/search
Disallow: /celebrities/search
Disallow: /location/drama/search
Disallow: /j/

二、robotparser常用方法

使用robotparser非常简单,我们用RobotFileParser类接受一个robots.txt文件链接参数即可。

urllib.robotparser.RobotFileParser(url='')

该类支持如下方法。

1. set_url()方法

该方法用于设置robots.txt文件的链接,实际上我们往往在创建RobotFileParser对象时就已经传入了链接,所以该方法经常用不到。

2. read()方法

该方法用于读取robots.txt文件并进行分析,在创建RobotFileParser对象后,我们必须要执行一次read()方法,不然其他所有的调用结果都没有意义。

3. parse()方法

该方法用来解析robots.txt文件,传入的参数是robots.txt某些行的内容,它会对其进行解析。

4. can_fetch()方法

该方法接受useragenturl两个参数,返回该UA(User-Agent,如某爬虫引擎、某搜索引擎)是否可以抓取这个url

5. mtime()方法

该方法返回上次抓取和分析robots.txt文件的时间,这可以帮助我们判断是否应该更新robots.txt的信息。

6. modified()方法

该方法将当前时间设置为上次抓取和分析robots.txt的时间,也就是说下次我们再调用mtime()时,返回的就是此时的时间。

7. crawl_delay()方法

该方法返回网站针对某个UA(User-Agent)建议的两次抓取的时间间隔。

8. request_rate()方法

该方法返回网站指定的Request-rate: x/n,比如Request-rate: 12/1m代表每1分钟可以抓取12个页面。

9. site_maps()方法

该方法以列表格式返回站点的站点地图。

怎么说呢,这个方法还是有用的,尤其是对于大型爬虫或者搜索引擎。它能帮助我们自动解析不同站点对爬虫的要求。

不过对我们个人来说,我们一般会直接打开站点的robots.txt看一眼,大概了解以后就关掉。如果它的要求能满足我们的要求,那我们就满足它的要求。如果它的要求不能满足我们的要求,那我们自然就不会满足它的要求。

如果大家真的那么乖,也就没有所谓的反爬与反反爬了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量化祛魅官 老Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值