14-网站地图爬虫
[toc]
1.5.3 网站地图爬虫
在第一个简单的爬虫中,我们将使用示例网站 robots.txt 文件中发现的网站地图来下载所有网页。为了解析网站地图,我们将会使用一个简单的正则表达式,从 <loc> 标签中提取出URL。
我们需要更新代码以处理编码转换,因为我们目前的 download 函数只是简单地返回了字节。而在下一章中,我们将会介绍一种更加稳健的解析方法—— CSS选择器 。下面是该示例爬虫的代码。
import re
def download(url, user_agent='wswp', num_retries=2, charset='utf-8'):
print('Downloading:', url)
request = urllib.request.Request(url)
request.add_header('User-agent', user_agent)
try:
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
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
def crawl_sitemap(url):
# download the sitemap file
sitemap = download(url)
# extract the sitemap links
links = re.findall('<loc>(.*?)</loc>', sitemap)
# download each link
for link in links:
html = download(link)
# scrape html here
# ...
现在,运行网站地图爬虫,从示例网站中下载所有国家或地区页面。
>>> crawl_sitemap('http://example.python-scraping.com/sitemap.xml')
Downloading: http://example.python-scraping.com/sitemap.xml
Downloading: http://example.python-scraping.com/view/Afghanistan-1
Downloading: http://example.python-scraping.com/view/Aland-Islands-2
Downloading: http://example.python-scraping.com/view/Albania-3
...
正如上面代码中的 download 方法所示,我们必须更新字符编码才能利用正则表达式处理网站响应。Python的 read 方法返回字节,而正则表达式期望的则是字符串。我们的代码依赖于网站维护者在响应头中包含适当的字符编码。如果没有返回字符编码头部,我们将会把它设置为默认值UTF-8,并抱有最大的希望。当然,如果返回头中的编码不正确,或是编码没有设置并且也不是UTF-8的话,则会抛出错误。还有一些更复杂的方式用于猜测编码(参见 https://pypi.python.org/pypi/chardet ),该方法非常容易实现。
到目前为止,网站地图爬虫已经符合预期。不过正如前文所述,我们无法依靠 Sitemap 文件提供每个网页的链接。下一节中,我们将会介绍另一个简单的爬虫,该爬虫不再依赖于 Sitemap 文件。
如果你在任何时候不想再继续爬取,可以按下Ctrl + C或cmd + C退出Python解释器或执行的程序。
如果你在任何时候不想再继续爬取,可以按下Ctrl + C或cmd + C退出Python解释器或执行的程序。