资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2014/8/7,#,爬虫学习心得,陈思哲,23320122203817,2012,级计算机一班,原来的代码有几点我们要改的,1,.,区号,点评网为不同的商区编订不同的号,而且值得注意的是它通常不是连着的,像开始时我们模仿北京的编号就一连串下来,那是错误的。我个人采取的方法是一个区一个区的爬,那怎么知道区号呢?,在网址最上方的最后有一个,r1841,那么就代表着鼓浪屿的区号,由于要求是一个区建一个文件,那么鼓浪屿就可以和别的思明区的编号建在一个列表里。,2.,指定一个文件来存放爬出来的信息,这些信息会以,txt,格式来保存。,f=open(D:/dianping/+str(time.strftime(ISOTIMEFORMAT)+.txt,a+),这个就是多,IP,爬虫,一个,IP,很容易就被发现并禁止,这个就是多客户端爬虫,单一个的客户端很容易被发现并禁掉,之后介绍一下搜索的方式,老师给的代码是一种典型的深度优先搜索,import urllib2,urllib,urllib2,模块定义的函数和类帮助打开,url,(主要是,HTTP,)在一个复杂的世界,-,基本和简要身份验证,重定向,,cookie,和更多。,import re,正则表达式,import time,提供各种时间函数,import string,字符串处理的函数,improt request,与,urlib,差不多,更简单,import socket,套,接字,套接字是为特定网络协议(例如,TCP/IP,,,ICMP/IP,,,UDP/IP,等)套件对上的网络应用程序提供者提供当前可移植标准的对象。它们允许程序接受并进行连接,如发送和接受数据。为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要。,Python,中的,random,模块用于生成随机数。,import user_agents,这个比较特殊,是人为定义的库,这个库存储了许多,IP,或是对点评网的访问方式,目的就是随机选一个,IP,访问以避免网站对单一,IP,登陆的封杀。,timeout=60,socket.setdefaulttimeout(timeout),#,设置,HTTP,或,Socket,访问超时,来防止爬虫抓取某个页面时间过长。,(,这个时间用秒,#,来算,),def get_status(url):,r=requests.get(url,allow_redirects=False),#allow_redirects=False,不允许间接地访问,用,request,库中的,get,函数来抓取,URL,return r.status_code,#,获取网页内容,def content_get(url):,try:,#,“,#,”是注释的意思,#proxy_ip=random.choice(proxyIP.proxy_list),#print proxy_ip,#proxy_support=urllib2.ProxyHandler(proxy_ip),#opener=urllib2.build_opener(proxy_support,urllib2.HTTPHandler),#urllib2.install_opener(opener),req=urllib2.Request(url),#,这个类是一个抽象的,URL,请求。,user_agent=random.choice(user_agents.user_agents),#,在刚才的,user_agents,里面随机找一个登录方法,req.add_header(User-Agent,user_agent),req.add_header(Referrer,url),print user_agent,#python,的输出函数是,print,page=urllib2.urlopen(req),content=page.read(),page.close(),return content,#,正常的话就用,content,来保存读出的结果并且一定要关闭文件并返回,content,except UnicodeDecodeError as e:,print(-UnicodeDecodeError url:,url),return ,#,解码错误则输出并返回空,except urllib2.HTTPError as e:,print(-HTTPError url:,url),return ,#,网站禁止爬虫则输出并返回空,except socket.timeout as e:,print(-socket timout:,url),return ,#,抓取超时则输出并返回空,except urllib2.URLError,e:,if hasattr(e,reason):,print Failed to reach a server.,print Reason:,e.reason,return ,elif hasattr(e,code):,#elif,相当于,else if,print The server couldnt fulfill the request.,print Error code:,e.code,return ,except Exception,e:,if DEBUG:,print e,return ,#if DEBUG,如果出错了,print e,return ,#,获取店铺的,url,def get_shopurl(url):,content=content_get(url),#,寻找店铺的实际,url,例如,/shop/6123204,用正则表达式,#find_shopurl=pile(rs*s*,re.DOTALL),find_shopurl=pile(rs*s*),re_next=find_next.search(content),return re_next,def get_info(url):,shop=content_get(url),#,店铺名称,title_re=pile(r(.*?),re.DOTALL),title=title_re.findall(shop),for i in title:,f.write(i.strip()+n),#,商铺一些信息,:,info_re=pile(r(.*?),info=info_re.findall(shop),for i in info:,f.write(i.strip()+),f.write(n),#,点评人数,count_re=pile(r(.*?),re.DOTALL),count=count_re.findall(shop),for i in count:,f.write(,点评人数,:+i+n),#,评分项目,item_re=pile(rs*(.*?),re.DOTALL),item=item_re.findall(shop),#,分数,socre_re=pile(rs*.*?(.*?),re.DOTALL),score=socre_re.findall(shop),for i in item:,f.write(i+),f.write(n),for i in score:,f.write(i+t),f.write(n),#,餐馆地址,address_re=pile(r(.*?),re.DOTALL),address=address_re.findall(shop),for i in address:,f.write(,地址,:+i.strip()+n),#,餐馆电话,tel_re=pile(r(.*?),re.DOTALL),tel=tel_re.findall(shop),for i in tel:,f.write(,电话,:+i.strip()+n),def get_comment(comment_all):,#,每个用户对应的评论块,part_re=pile(r,re.DOTALL),part=part_re.findall(comment_all),for i in part:,#,用户,member_re=pile(r(.*?),re.DOTALL),member=member_re.findall(str(i),for j in member:,f.write(,用户,:+j.strip()+n),#,口味,环境,服务评分,taste_re=pile(r(.*?),re.DOTALL),taste=taste_re.findall(str(i),for j in taste:,f.write(j.strip()+t),f.write(n),#,评论,comment_re=pile(r(.*?),re.DOTALL),comment=comment_re.findall(str(i),for j in comment:,f.write(j.strip()+t),f.write(n),补充,以上这些正则字符都是一些匹配,编程人员在原网址的源代码中查出这些关键的匹配符,然后用,python,的正则形式表示出,对于爬虫十分方便。,上面的一些方法(函数)用,#def,的形式给出,与,c,等语言的函数定义不同,Python,作为一种脚本语言有其特殊性,我们用一种叫,ULIPAD,的工具进行编辑,我们只是编辑而非编译。另外,它是一种面向对象的语言,它采用类做定义,并且一个变量也是一个类。,一个良好的爬虫代码,应该有比较多的关键参数的输出,以方便查看程序目前的状态。,比如下一页,的,count,,用来记是第几组评论,。,如果停下来了,且程序正在运行,那么可能是正在收集一组的评论一起发送,或是不幸掉进了爬虫陷阱。,该,程序其中的一个特点就是判断分支多,而且就是错误,也要区分是何种类型的错误。比如众多的,except,分支(类似于,C,中的,switch,分支),这样是严谨而科学的。因为爬虫中可能出现的问题通常是很难预测的。,同样一个程序,我曾经两次去跑(没有修改)。结果第一次过了几组就卡住了,然后第二组就可以都跑完。,就起原因我认为是,IP,活动过于平凡被禁掉了,或是掉进陷阱。,他山之石,Python,提供了许多,Module,,通过这些,Module,,可以很简单的做一些工作。比如,要获得,cloga,这个词在百度搜索结果页中的排名结果(排名结果,+URL,),这就是一个很简单的爬虫需求。,首先,要通过,urllib2,这个,Module,获得对应的,HTML,源码。,通过上面这三句就可以将,URL,的源码存在,content,变量中,其类型为字符型。,接下来是要从这堆,HTML,源码中提取我们需要的内容。用,Chrome,查看一下对应的内容的代码(也可以用,Firefox,的,Firebug,)。,可以看到,url,的信息存储在,span,标签中,要获取其中的信息可以用正则式。,pile,是将字符串编译为用于,python,正则式的模式,字符前的,r,表示是纯字符,这样就不需要对元字符进行两次转义。,re.findall,返回的是字符串中符合,results_pat,的列表,由于在,results_pat,中使用了子表达式,所以,results,存储的就是子表达式所匹配的内容,即,与,之间的内容。,特别鸣谢,1.,某位科研楼,305,的学长在我软件崩溃之时教我弄好了环境变量。,2.,某位,05,级厦大老学长(现在已经是某公司的项目经理),他讲解了正则表达式的使用。,3.,刘宏同学,他和我一起讨论了很多技术细节。,4.,各位老师同学的默默支持和关心。,
展开阅读全文