python爬虫实例详细介绍之爬取大众点评的数据,,python 爬虫实


python 爬虫实例详细介绍之爬取大众点评的数据



一.

Python作为一种语法简洁、面向对象的解释性语言,其便捷性、容易上手性受到众多程序员的青睐,基于python的包也越来越多,使得python能够帮助我们实现越来越多的功能。本文主要介绍如何利用python进行网站数据的抓取工作。我看到过利用c++和Java进行爬虫的代码,c++的代码很复杂,而且可读性、可理解性较低,不易上手,一般是那些高手用来写着玩加深对c++的理解的,这条路目前对我们不通。Java的可读性还可以,就是代码冗余比较多,同样的一个爬虫,java的代码量可能是python的两倍,感觉也没有python容易上手。因此,建议大家以后如果对爬虫有兴趣的话直接使用python就好。

二.本文首先爬取大众点评-北京的火锅这个条目下的部分数据。下面,我主要针对如何爬取数据进行讲解,针对数据进行分析的部分就略过。会根据我自己的理解和经验对代码进行详细的分析,比较适合初学者,高手请出门右转。由于是针对初学者,所以我最大程度地将代码进行精简,当然也因此删去了一些功能。

三、注意!

不要盲目的直接把代码复制直接运行,最好先看完本文,然后再运行。因为我是在ubuntu14.04下运行的我的代码,因此在获取数据时的编码格式不一样,输出信息到窗口时的编码也会有所不同,在Linux下默认编码是utf-8,而在windows下默认编码是gbk,所以,如果系统不同,直接运行代码,可能会输出乱码,这不代表我的代码有问题。需要注意的问题,在本文中我基本上都给了讲解,如果还有问题的话,欢迎留言探讨。

本人的浏览器为forefox,不同浏览器的查看元素的方法和界面也会有所不同,我在下文进行介绍时,只能以我的浏览器为准,不同的浏览器可以自己找一下相应的东西,一般不会差太多。

四.闲话少叙,直接上代码。

[python]view plaincopy

#-*-coding:utf-8-*-

importre

frombs4importBeautifulSoup

importjson

importthreading

fromrequestsimportSession

classdazp_bj:

def__init__(self,category):

self.baseUrl=‘http://www.dianping.com‘

self.bgurl=category[0]

self.typename=category[1]

self.page=1

self.pagenum=10#设置最大页面数目,大众点评每个条目下最多有50页,可以根据自己需求进行设置

self.headers={

"Host":"www.dianping.com",

"User-Agent":"Mozilla/5.0(X11;Ubuntu;Linuxx86_64;rv:48.0)Gecko/20100101Firefox/48.0",

#此User-Agent是我本人的参数,在使用时记得修改为自己的参数,如何获取下四.4部分有讲解

"Referer":"http://www.dianping.com/beijing",

}

defstart(self):

self.s=Session()#定义一个Session()对象

printself.bgurl,self.typename

print"pleasewaitfor15"

dazp_bj.__parseHtml(self,self.bgurl)#调用__parseHtml函数

print‘getdatadown‘

def__parseHtml(self,preurl):

_json=dict()#定义一个字典用以存储数

html=self.s.post(preurl,headers=self.headers).text#发送请求,获取html

soup=BeautifulSoup(html,‘lxml‘)#进行解析

name=[‘商家名称‘,‘评论数量‘,‘人均消费‘,‘地址‘,‘评分‘,‘链接‘]

forliinsoup.find(‘div‘,class_="shop-wrap").find(‘div‘,id="shop-all-list").ul.find_all(‘li‘):

info=li.find(‘div‘,class_=‘txt‘)

_json[name[0]]=info.find(‘div‘,class_=‘tit‘).a.h4.get_text().encode(‘utf-8‘)

_json[name[1]]=int(info.find(‘div‘,class_=‘comment‘).find(‘a‘,class_="review-num").b.get_text().encode(‘utf-8‘))

_json[name[2]]=int(re.sub(‘¥‘,‘‘,info.find(‘div‘,class_=‘comment‘).find(‘a‘,class_="mean-price").b.get_text().encode(‘utf-8‘)))

_json[name[3]]=info.find(‘div‘,class_=‘tag-addr‘).find(‘span‘,class_=‘tag‘).get_text().encode(‘utf-8‘)+info.find(‘div‘,class_=‘tag-addr‘).find(‘span‘,class_=‘addr‘).get_text().encode(‘utf-8‘)

_json[name[4]]=float(info.find(‘span‘,class_=‘comment-list‘).find_all(‘b‘)[0].get_text())+float(info.find(‘span‘,class_=‘comment-list‘).find_all(‘b‘)[1].get_text())+float(info.find(‘span‘,class_=‘comment-list‘).find_all(‘b‘)[2].get_text())

_json[name[5]]=self.baseUrl+info.find(‘div‘,class_=‘tit‘).a[‘href‘]

withopen(self.typename+‘.json‘,‘a‘)asoutfile:

json.dump(_json,outfile,ensure_ascii=False)

withopen(self.typename+‘.json‘,‘a‘)asoutfile:

outfile.write(‘,\n‘)

self.page+=1

ifself.page<=self.pagenum:

self.nexturl=self.baseUrl+soup.find(‘div‘,class_=‘page‘).find(‘a‘,class_=‘next‘)[‘href‘]#获得下一页的链接

dazp_bj.__parseHtml(self,self.nexturl)

if__name__==‘__main__‘:

cat=[(r‘http://www.dianping.com/search/category/2/10/g110‘,u‘火锅‘)]

obj=list()

obj.append(dazp_bj(cat[0]))

[threading.Thread(target=foo.start(),args=()).startforfooinobj]#多线程执行obj列表中的任务


五.上面是所有代码。接下来则对代码进行精细的讲解。

1.# -*- coding:utf-8 -*- #这句代码是在文件的开头设置好编码的格式,这样就能够在文件里写中文,否则python2.7会默认使用ASCII编码。个人建议最好在所有的.py文件的开头都写上这句代码,防止不必要的错误。有时候这样设置后在爬取某些网站时仍然会出现问题,比如说会报这样的错误:UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: ordinal not in range(128) 。这种情况下可以加如下几行代码:

[python]view plaincopy

importsys

reload(sys)

sys.setdefaultencoding("utf-8")

暂时不知道为什么会这样,但是这样就可以解决问题了。据说python2.7在这方面特别容易出错,在python3中则会好很多,可能以后会转到python3吧,差别应该不大,新手可以直接学3.

2.现在讲一下引用的包。re是正则表达式,对网页进行解析时很有用,非常强大,当你掌握了正则表达式的使用后,你就可以在各个网页中来回驰骋了;json是一种数据格式,我利用json文件在保存爬取到的字典数据,感觉json保存字典数据很强大,调用读取都很便捷。之前看到一个txt文件保存的字典数据,在读数据的时候很麻烦,没有json便捷;threading 是多线程,可以提高爬取效率,本文中因为只抓了一个链接,因此没有用到它的功能,在cat中多加入几个链接,并append到obj中就可以使用这个功能;bs4是python的一个很强大的对网页进行解析的包,如果没有这个包,如果要解析数据都是要使用正则表达式的,那个场面一定很惨烈。python也提供了另一种方式方便查找网页中的标签:xpath,只用过一次,配合firefox的firebug很好用,在定位到感兴趣的标签后直接右键即可获得该标签的xpath路径,省得我们还要一个一个标签去找,但是当我们爬取的网站比较大、复杂的时候,这种方式可能就不是那么适用了,因为不同条目的同一种类的数据可能在不同的位置,或者有些数据没有值的情况下这个标签就不存在,这个时候只能使用beautifulsoup来根据id、class、name等值准确定位到标签;requests是向服务器发送请求的包,有post和get两张方法,可以传入很多参数,如headers,cookies,data,params等,headers是你浏览器的请求头数据,传入这个参数可以将你的爬取访问伪装成浏览器的正常访问,对一些网站有效,有些网站则需要传入cookies,data和params是在其他情况下需要传入的参数,初学者一般用不到,在此就不赘述,需要的时候百度基本上可以找到方法。requests下的Session()方法和request有点相似,也包括get和post方法,传的参数也基本上差不多,但是会话对象requests.Session能够跨请求地保持某些参数,比如cookies,即在同一个Session实例发出的所有请求都保持同一个cookies,而requests模块每次会自动处理cookies,这样就很方便地处理登录时的cookies问题。但是本文中貌似不需要使用session,只是习惯性的使用这个,大家可以修改后试一下:将后文的self.s替换为requests .

3.首先定义了一个类,类下面有很多方法。__init__是对类的参数进行初始化,类内的全局变量都可以在此设置,在其他地方设置也可,不过要在变量名前加上global。start(),类中的方法和函数都在此进行调用,start可以说是类的入口。__parseHtml是定义的爬取数据的主函数。

4.下面介绍如何针对每个数据条目定制解析语句,以及如何获得headers参数。

技术分享

打开页面之后右键然后选择查看元素(有些浏览器是检查元素,我使用的是firefox,注意不是查看源代码)然后点网络(Network),然后点左上角“所有”旁边的删除符号,然后点击重新载入(或者刷新页面),可以看到下图所示的情况:

技术分享

点击最上面的那一条,得到下图,请求头信息、cookie、参数等信息都在这里。上面代码中的headers内的User-Agent是我的浏览器信息,在使用时需要根据自己的电脑进行修改。请求头中有些数据是不需要的,因此我只选择了几条。

技术分享


本文出自 “李世龙” 博客,谢绝转载!

python爬虫实例详细介绍之爬取大众点评的数据

相关内容

    暂无相关文章

评论关闭