关于《Python写网络爬虫》第一章总结
1. 关于爬虫错误处理
比如在爬虫里 下载网页时, 我们可能会遇到一些无法控制的错误, 比如请求的页面可能不存 在。 此时,urlli b2 会抛出异常, 然后退出脚本。下面再给出一个更健壮的版 本, 可以捕获这些异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#-*- coding=utf8 -*- import urllib2 def download(url): try: print urllib2.urlopen(url).read() except urllib2.URLError as e: #也可以是HTTPError等,看实际报错修改 print "error" print e.code #可以打印出来错误代号如404。 print e.reason #可以捕获异常 if __name__=='__main__': url = 'http://www.rainweb.site/footer.php' download(url) |
2. 重试下载
下载时遇到的错误经常 是临时性的, 比如服务器 过载时返回的 503Service Unavailable错误。对于此类错误 我们可以尝试重新下载,不过, 我们不需要对所有错误都尝试重新下载。 如果服务器返回的是404 Not Found 这种错误,则说明该网页目前并不存 在,再次尝试 同样的请求一般 也不会出现不同的结果。4xx 错误发生在请求存在问题时,而5xx 错误则发生在服务端存在问题时。 所以, 我们只需要确保download函数在 发生Sxx 错误时重试下载 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#-*- coding=utf8 -*- import urllib2 def download(url, num=2): try: print urllib2.urlopen(url).read() except urllib2.URLError as e: print "error", e.reason #可以捕获异常 if num>0: if hasattr(e,'code') and 500<=e.code<600: download(url,num-1) if __name__=='__main__': url = 'http://www.rainweb.site/footer.php' download(url) |
当 download函数遇到Sxx 错误码时, 将会递归调用 函数自身进行重试。 此外, 该函数还增加了一个参数, 用于设定重试下载的次数, 其默认值为两次
3. 设置用户代理
### 默认情况下,urllib2 使用 Python-urllib/ 2 . 7 作为用户代理下载网 页内容, 其中 2 . 7是 Python 的版本号 。User-Agent:python-urllib2/.7
1 2 3 4 5 |
User_agent = 'wswp' headers = {'User_agent':user_agent} request = urllib2.Request(url,headers=headers) html = urllib2.urlopen(request) |
4. 抓取页面中所有符合要求的链接
有时页面中许多链接需要下载,单单改变url中几个数字是无法全部找到的,下面的例子可以根据你所输入的正则表达式匹配到所有符合要求的url,并且可以将网页中的相对链接转换为绝对链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#-*- coding=utf8 -*- import urllib2 import re import urlparse def download(url): try: html = urllib2.urlopen(url).read() except urllib2.URLError as e: print "error" print e.code #可以打印出来错误代号如404。 print e.reason #可以捕获异常 html = None return html #要抓取的主页面和匹配的正则表达式 def link_crawler(seed_url,link_regex): crawl_queue = [seed_url] #将第一个url放入 html = download(seed_url) #获取页面所以信息 for link in get_links(html):#遍历所得到的url if re.match(link_regex, link):#匹配输入的正则表达式 link = urlparse.urljoin(seed_url,link) print link crawl_queue.append(link) print crawl_queue # for url in crawl_queue: # html = download(url) def get_links(html):#返回所需要的url webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']',re.IGNORECASE) # print webpage_regex.findall(html) # exit() return webpage_regex.findall(html) if __name__=='__main__': link_crawler('','') |