使用urllib模块编写网络爬虫



前言

网络抓取通常针对特定网站,并在这些站点上获取特定信息。网络抓取用于访问这些特定的页面,如果站点发生变化或者站点中的信息位置发生变化,则需要进行修改。




一、下载网页

要想抓取网页,我们首先需要将其下载下来。下面的示例脚本使用Python的urllib模块下载URL。
下载时遇到的错误经常是临时性的,比如服务器过载时返回的503 Service Unavaailable错误。对于此类错误,我们可以短暂等待后尝试重新下载,因为这个服务器错误现在可能已经解决。不过,我们不需要对所有错误都尝试重新下载。如果服务器返回的时404 Not Found这种错误,这说明该网页目前并不存在,再次尝试同样的请求一般也不会出现不同的结果。
互联网工程任务组(Internet Engineering Task Force)定义了HTTP错误的完整列表,从中可以了解到4XX错误发生在请求存在错误时,而5XX错误则发生在服务器端存在错误时。所以,我们只需要确保download函数在发生5XX错误时重新下载即可。

二、实现代码

1.代码中无引用代理

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


def download(url, num_retries=2, user_agent='wswp'):
    print('Downloading:', url)
    request = urllib.request.Request(url)
    request.add_header('User-agent', user_agent)
    # 当出现下载或URL错误时,该函数能够捕获异常,然后反回None。
    try:   
        html_doc = urllib.request.urlopen(request).read()
    except (URLError, HTTPError, ContentTooShortError) as e:
        print('Download error:', e.reason)
        html_doc = None
        # 对于5XX错误重试下载
        if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                # recursively retry 5xx HTTP errors
                return download(url, num_retries=num_retries - 1)
    return html_doc

2.代码中引入代理

目前很多网站都会设置相对应的防爬虫机制,这是因为有一部分人在实际的爬虫主权过程中会进行恶意采集或者恶意攻击,通常情况下,防爬虫程序是通过IP来识别哪一些是机器人用户,因此可以使用可用的http代理解决。

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


def download(url, user_agent='wswp', num_retries=2, charset='utf-8', proxy=None):
    print('Downloading:', url)
    request = urllib.request.Request(url)
    request.add_header('User-agent', user_agent)
    # 当出现下载或URL错误时,该函数能够捕获异常,然后反回None。
    try:
        if proxy:
            proxy_support = urllib.request.ProxyHandler({'http': proxy})
            opener = urllib.request.build_opener(proxy_support)
            urllib.request.install_opener(opener)
        resp = urllib.request.urlopen(request)
        cs = resp.headers.get_content_charset()
        if not cs:
            cs = charset
        html = resp.read().decode(cs)
    except (URLError, HTTPError, ContentTooShortError) as e:
        print('Download error:', e.reason)
        html = None
        # 对于5XX错误重试下载
        if num_retries > 0:
            if hasattr(e, 'code') and 500 <= e.code < 600:
                # recursively retry 5xx HTTP errors
                return download(url, num_retries - 1)
        return html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值