第一章的内容比较基础,就是使用urllib2的模块来下载网页数据。并且一步步的完整代码。
在学习爬虫中,第一个遇到的函数很可能就是urllib2(相当于python3中的urllib.request)。p9
import urllib2
#url 是传入的网址
response=urllib2.urlopen(url)基本网站都可采用这种方法来进行访问,但是不够完善,下面推出捕捉服务器异常(5xx),重新下载的加强版本,遇到错误再次进行下载。p10
import urllib2
def download(url,num=2):
print('download:',url)
try:
html=urllib2.urlopen(url).read()
except urllib2.URLError as e:
print ('dowmload error',e)
html=None
if num>0:
#hassattr 判断属性 hasattr(list,'append')
if hasattr(e,'code') and 500<=e.code<600:
return download(url,num-1)
return html
if __name__=='__main__':
url='http://jandan.com/'
download(url)
设置用户代理User-Agent,解析robots以及ip代理。写出download的完整版本。
# -*- coding: utf-8 -*-
#p11 添加用户代理,p18判断用户是否友好,p19 ip代理
import urllib2
import robotparser
def download(url,user=None,proxy=None,num=2):
#robotparser设定,解析robots.txt
req=urllib2.Request(url)
if user:
rp=robotparser.RobotFileParser()
rp.set_url(url+'/robots.txt')
rp.read()
if rp.can_fetch(user,url)==False:
print('UserError')
req.add_header('User-Agent',user)
#ip代理
if proxy:
opener=urllib2.build_opener()
proxy_params={'http':proxy}
opener.add_handler(urllib2.ProxyHandler(proxy_params))
try:
html=urllib2.urlopen(req).read()
print('download:',url)
except urllib2.URLError as e:
print ('dowmload error',e)
html=None
if num>0:
#hassattr 判断属性 hasattr(list,'append')
if hasattr(e,'code') and 500<=e.code<600:
return download(url,num-1)
return html
if __name__=='__main__':
url='http://jandan.com/'
print('start')
download(url,user='GoodCrawler')
其中第17页的link_crawler函数,对于要下载的数据,这里使用正则表达式,后面会用到CSS选择器来进行筛选,会更加简单易懂。
# -*- coding: utf-8 -*-
#最终版本,没加下载限速,如需要直接将类添加即可
#p21爬虫陷阱,设置访问深度
from download2 import*
import re
import urlparse
def link_crawler(url,link_regex,max_depth=-1):
#存储URL,避免重复下载
crawl=[url]
seen={}
seen[url]=0
while crawl:
url=crawl.pop()
html=download(url)
#提取访问网页(包括添加link_regex网页)的深度,添加一次depth+1
depth=seen[url]
#如果max_depth为0,则不执行,只访问url
#如果max_depth为1,下载url+link的网页
if depth!=max_depth:
if link_regex:
for i in get_links(html):
#re.match 从开始判断i中是否有/view
if re.match(link_regex,i):
link=urlparse.urljoin(url,i)
if link not in seen:
#link为最初url+i组成,所以深度+1,这就是访问深度
seen[link]=depth+1
crawl.append(link)
#已经将链接添加到seen中,链接地址列表添加完毕
#print seen
print ('下载完成')
def get_links(html):
# re.IGNORECASE忽略大小写
web=re.compile(']+href=["\'](.*?)["\']',re.IGNORECASE)
return web.findall(html)
if __name__=='__main__':
url='http://example.webscraping.com'
print('start')
#link_crawler(url,link_regex='/view',max_depth=0)
link_crawler(url,link_regex='/view',max_depth=1)