resource爬虫修炼之道爬虫专题

1.2 爬虫修炼之道——编写一个爬取单页面的网络爬虫

2017-02-17  本文已影响491人  王伟_同学

欢迎大家关注我的专题:爬虫修炼之道

上篇 爬虫修炼之道——网站基本知识 主要讲解了一些和网站相关的知识,对于我们之后理解爬虫有很多好处。这一篇就要编写第一个爬虫了。我们使用的python版本为2.7,此外涉及到的python模块包括:

下载单个网页

想要爬取网页数据,首先需要将其下载下来,我们都知道,每个网页其实都是由一个个html文件组成,我们要做的就是将该文件从服务器下载到本地。这儿我们使用urllib2模块来实现。

urllib2模块的基本用法可参考这篇文章:http://www.pythontab.com/html/2014/pythonhexinbiancheng_1128/928.html

import urllib2


def download(url):
    """
    url: 要下载的url页面

    """
    print 'Downloading: url %s' % url
    try:
        html =  urllib2.urlopen(url).read()
    except urllib2.HTTPError, e:
        print 'URL: %s,HTTP Error %s: %s' % (url, e.code, e.msg)
        html = None
    except urllib2.URLError, e:
        print 'URL: %s, urlopen Error %s' % (url, e.reason)
        html = None
    return html

上面的代码可以实现指定url页面的下载,如果出错(例如,提供了一个错误的URL),则会将错误打印到屏幕上。

失败重试下载

下载出错时,服务器会返回特定的 HTTP状态码,如果状态码为4xx,表示请求存在问题,说明我们应该检查自己的请求;如果状态码为5xx,表示服务器存在问题,有可能只是暂时的,这时,我们需要尝试重新下载,但是必须限定一个下载次数。

def download(url, num_retries=2):
    """
    url: 要下载的url页面
    num_retries: 碰到5xx状态码时尝试重新下载的次数
    """
    print 'Downloading: url %s' % url
    try:
        html = urllib2.urlopen(url).read()
    except urllib2.HTTPError, e:
        print 'URL: %s,HTTP Error %s: %s' % (url, e.code, e.msg)
        html = None
        if num_retries > 0 and 500 <= e.code < 600:
            return download(url, num_retries - 1)
    except urllib2.URLError, e:
        print 'URL: %s, urlopen Error %s' % (url, e.reason)
        html = None
    return html

例如下载 “http://httpstat.us/500” 网址。

重试下载页面

设置下载超时

有时候我们可以规定一个页面多长时间内没有下载完成则放弃,即下载超时。想要实现该功能,可以通过urllib2.urlopen方法的timeout参数来指定超时时间,我们指定它默认为3s。即

urllib2.urlopen(request, timeout=3)

设置用户代理

有些网址会针对爬虫做一些限制,比如,必须设置用户代理,即User-Agent。我们可以使用urllib2.Request类来设置用户代理。

我们先用上面的download方法来下载糗事百科首页(http://www.qiushibaike.com/),运行后,我们会出错,如下图所示:

直接抓取糗百出粗

现在我们要设置用户代理(User-Agent),首先需要根据url和headers生成一个urllib2.Request类的实例,其中User-Agent就是在headers中封装的。更新后的 <a id="1-2-download" href="#1-2-download">download</a> 如下:

def download(url, user_agent='crawl', num_retries=2, timeout=3):
    """
    下载一个URL页面
    :param url: 要下载的url页面
    :param user_agent: 用户代理
    :param num_retries: 碰到5xx状态码时尝试重新下载的次数
    :param timeout: 超时时间,单位为s
    :return:
    """
    print 'Downloading: url %s' % url
    headers = {'User-Agent': user_agent}
    request = urllib2.Request(url, headers=headers)
    try:
        html = urllib2.urlopen(request, timeout=timeout).read()
    except urllib2.HTTPError, e:
        print 'URL: %s,HTTP Error %s: %s' % (url, e.code, e.msg)
        html = None
        if num_retries > 0 and 500 <= e.code < 600:
            return download(url, num_retries = num_retries - 1)
    except urllib2.URLError, e:
        print 'URL: %s, urlopen Error %s' % (url, e.reason)
        html = None
    return html

现在通过download方法来下载糗百官网,结果如下:

设置用户代理后抓取糗百官网

用户代理可以自己定义之外,也可以使用浏览器自带的用户代理,比如在chrome浏览器地址栏中输入:chrome://version/ ,可以看到相应的版本信息,我的显示如下:

chrome版本信息

我们也可以将它作为我们的用户代理,这样做的话,就是模拟浏览器来访问了。

完整代码参见:https://github.com/Oner-wv/spider_note/blob/master/chapter01/1.2.py

下篇我们将讲解如何编写爬取多个页面的爬虫:爬虫修炼之道——编写一个爬取多页面的网络爬虫

欢迎大家关注我的专题:爬虫修炼之道

上一篇下一篇

猜你喜欢

热点阅读