用python进行网络爬虫(一)--编写第一个爬虫

本文是一个python3爬虫入门教程,介绍如何下载网页、设置用户代理、ID遍历爬虫以及链接爬虫。通过示例解释了如何处理网页下载中的重试和设置用户代理,以及如何利用ID遍历网站内容。同时提到了requests库在爬虫中的重要性。

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

本文是一个python3爬虫入门教程,需要注意的是你需要有python基础,不过也仅需要掌握简单的用法即可。

前言

网络爬虫被用于许多领域,收集不太容以其他格式获取的信息。

需要注意的是,网络爬虫当你抓取的是现实生活中真实的公共的公共数据,在合理的使用规则下是允许转载的。
相反,如果是原创数据或是隐私数据,通常受到版权显示,而不能转载。 请记住,自己应当是网络的访客,应当约束自己的抓取行为,否则会造成不良后果。

我们将从零开始,逐步完善一个高级网络爬虫。.

下载网页

下面的示例脚本使用urllib模块下载url

import urllib.request
def download(url):
	return urllib.request.urlopen(url).read()

当传入url时,该函数将会下载网页并返回其HTML。不过这样不够稳健,因为我们访问网页的时候可能会遇到问题,比如页面不存在。
因此下面给出一个更稳健的版本:

import urllib.request
from urllib.error import URLError,HTTPError,ContentTooShortError
def download(url):
    print('Downloading:')
    try:
        html = urllib.request.urlopen(url).read()
    except (URLError,HTTPError,ContentTooShortError) as e:
        print('download:',e.reason)
        html = None
    return html

当网址不正确的时候你就可能看到:
在这里插入图片描述

1. 重试下载
下载时遇到的错误很多时候是临时性的,比如服务器过载时返回的503错误。对于这类错误我们可以等待一下再尝试访问。不过不是所有的错误都需要重试,比如404,这说明网页页面不存在。
下面给出新版本代码,当download遇到5xx错误码时,将会递归调用函数自身进行重试,当然我们还增加了重试的次数:
def download(url,num_retries=2):
    print('Downloading:',url)
    try:
        html = urllib.request.urlopen(url).read()
    except (URLError,HTTPError,ContentTooShortError) as e:
        print('download:',e.reason)
        html = None
        if num_retries>0:
            #hasattr() 函数用于判断对象是否包含对应的属性。
            if hasattr(e,'code') and 500<=e.code<600:
                return download(url,num_retries-1)
    return html

测试代码:
在这里插入图片描述

2. 设置用户代理

默认情况下,urllib使用python-urllib/3.x 作为用户代理下载网页,3.x是python版本号,但是有些网站会封禁这个默认代理。下面我们来控制用户代理的设定:('wswp’是web scraping with python的缩写)

def download(url,user_agent='wswp',num_retries=2):
    print('Downloading:',url)
    request = urllib.request.Request(url)
    request.add_header('user_agent',user_agent)
    try:
        html = urllib.request.urlopen(url).read()
    except (URLError,HTTPError,ContentTooShortError) as e:
        print('download:',e.reason)
        html = None
        if num_retries>0:
            #hasattr() 函数用于判断对象是否包含对应的属性。
            if hasattr(e,'code') and 500<=e.code<600:
                return download(url,num_retries-1)
    return html

ID遍历爬虫

在这里我们利用网站结构的特点,更加轻松的访问所有内容
下面是一个地图示例网站的url

  • http://example.python-scraping.com/places/default/view/Afghanistan-1
  • http://example.python-scraping.com/places/default/view/Aland-Islands-2
  • http://example.python-scraping.com/places/default/view/Albania-3

显而易见的是,这些url只在最后的一部分有区别,包含 页面别名ID 。在url中包含页面别名是非常常见普遍的做法,可以对搜索引擎优化起到帮助作用。一般情况下,Web服务器会忽略这个字符串,只使用ID来匹配数据库中的相关记录。我们将他移除再访问看看:
在这里插入图片描述
可以看出,网页依旧可以访问。现在我们就可以忽略别名,只使用ID下载所有国家或地区的页面:

itertools.count([n]):创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算

import itertools
def crawl_site(url):
    for page in itertools.count(1):
        pg_url = '{}{}'.format(url,page)
        html = download(pg_url)
        if html is None:
            break

接下来使用该函数传入基础url:
在这里插入图片描述
在这段代码中,我们对ID进行遍历,直到出现错误停止。不过有时候页面的有些记录可能已经被删除,数据库ID之间并不是连续的,在这种情况下只要访问到某个间隔点显然爬虫就会退出。下面是改进版本,在该版本下连续多次下载错误才会退出程序。

def crawl_site(url,max_errors=5):
    for page in itertools.count(1):
        pg_url = '{}{}'.format(url,page)
        html = download(pg_url)
        if html is None:
            num_errors += 1
            if num_errors == max_errors:
                break
            else:
                num_errors =0

上面代码中爬虫需要连续5次下载错误才会停止遍历,在爬取网站中,遍历ID是一个很便捷的方法。
爬取wall.alphacoders.com下的英雄联盟壁纸这篇文章中,就典型的利用了遍历ID获取一个页面下的所有图片。

但是这种方法也无法保证一直可用,比如有一些网站会检查页面别名是否在URL,如果不是则会返回404.

你可能在爬取过程中已经遇到 TOO MANY REQUESTS 下载错误信息,我们将在后面解决它。

链接爬虫

到目前为止,我们已经使用地图示例网站的结构特点实现了两个简单爬虫。不过对于另一些网站,我们需要让爬虫表现得更像普通用户,跟踪链接,访问敏感内容。

例如在爬取英雄联盟壁纸的文章中,查看壁纸网页源码时:
在这里插入图片描述

<div class='boxgrid'>
	<a href="big.php?i=536426"

其中big.php?i=536426,该链接只有网页的路径部分,而没有协议和服务器部分,也就是说这是一个相对链接,由于浏览器知道你在浏览哪个网页,并且能采取相应措施处理这些链接,因此用浏览器浏览时,相对链接是可以正常工作的。但是urllib没有上下文,为了让爬虫正常工作,我们需要将链接转为绝对链接的形式,以包含定位网页的所有细节。
如 https://wall.alphacoders.com/big.php?i=536426

使用requests库

尽管我们使用urllib也能实现爬虫,但是主流的爬虫一般用requests库来管理复杂的HTTP请求。
后面我们大部分时候将使用它,因为它足够强大且简单。
安装:

pip install requests
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值