最近,突然有想学习下爬虫,其实,在当初看《集体智慧编程》的时候,就接触过爬虫,只不过没怎么深入学习python下工具包:BeatifulSoup。这个包主要用来解析html和xml文件。我们做爬虫主要是就是为了抓取网页中我们需要的信息,利用BeatifulSoup,我们可以很快的解析网页文件,获取网页中我们需要的信息。实际案例,我以百度旗下《今晚看啥》网站为例,抓取电影评分,标签,作者,标题等等。
其中电影阿甘正传的网址:http://kansha.baidu.com/movie/1054。
电影基本信息如下:
这幅图,中我们得到了电影的标题,导演,演员,国家,豆瓣,IMDb评分。
在下面的图,我们知道网友的评分:
这些信息,就是我们要抓取的信息。
我们根据url,抓取网页信息,通过BeatifulSoup包来解析。值得提的是:网页评论部分,有上下页切换,我们点击切换的时候,url并没有改变。但是,你仔细分析下网页源码,你会发现,其实有个地方是系统隐藏了。实际url:http://kansha.baidu.com/movie/1054?up=n,n表示页数。
下面,我贴出,写的抓取代码:
import urllib2 import string import re from BeautifulSoup import BeautifulSoup # get a movie review score by users; def get_user_review_score(movie_id): base_url = 'http://kansha.baidu.com/movie/' suffix_url = 'http://kansha.baidu.com/movie/' + str(movie_id) + '?up=' raw_url = 'http://kansha.baidu.com/movie/' + str(movie_id) user_scores = [] try: c = urllib2.urlopen(raw_url) except: print 'can not open this webpage...' return None s = BeautifulSoup(c.read()) pages = s.find('a',{"class":"last hidden"})['href'].split('=')[1] pages = string.atoi(pages) for i in range(1,pages+1): url = "%s%d"%(suffix_url,i) try: c = urllib2.urlopen(url) except: print 'can not open this webpage...' return None s = BeautifulSoup(c.read()) review = s.findAll('div',{"class" : "user-review-wide"}) for e in review: if e.a['href'] != '#' and e.find(attrs = {"class" : "badge badge-warning"}) != None: print e.a print e.span.contents[0] user_id = e.a['href'].split("/")[2] score_by_user = string.atoi(str(e.span.contents[0])) user_scores.append((user_id, score_by_user)) print "The %d page"%i print "crawering is end..." print user_scores return user_scores # tag : directors ,actors, gen_labels, country, douban_review, IMDb_review ; def get_tags_movie(movie_id): raw_url = 'http://kansha.baidu.com/movie/' + str(movie_id) try: c = urllib2.urlopen(raw_url) except: print 'can not open this webpage...' return None s = BeautifulSoup(c.read()) directors = s.findAll('a',{'class': 'label label-director normal-tooltip'}) actors = s.findAll('a',{'class': 'label label-actor normal-tooltip'}) genome = s.findAll('a',{'class': 'label label-genome normal-tooltip'}) country = s.findAll('a',{'class': 'label label-country normal-tooltip'}) Douban = s.find(text = u'\u8c46\u74e3') Douban_score = Douban.next.next.contents IMDb = s.find(text= 'IMDb') IMDb_score = IMDb.next.next.contents print directors,actors,genome,country,[Douban_score, IMDb_score] directors_names = [elem.contents for elem in directors] actors_names = [elem.contents for elem in actors] genome_names = [elem.contents for elem in genome] country_names = [elem.contents for elem in country] return [ directors_names, actors_names,genome_names,country_names,[Douban_score,IMDb_score]] def get_movie_tile(movie_id): raw_url = 'http://kansha.baidu.com/movie/' + str(movie_id) try: c = urllib2.urlopen(raw_url) except: print 'can not open this webpage...' return None s = BeautifulSoup(c.read()) movie_title = str(s.title.contents).replace(" "," ") print movie_title return movie_title
上面主要涉及三个函数:第一个是抓取网友评分:(user_id, score),第二个是抓取电影标签,豆瓣,IMDb的评分,第三个:电影标题。
最后,我想说明下,其实上面的工作很简单,用的也只是BeautifulSoup包里面一小部分东西,并且是针对静态网页来做的。我们知道,现在很多网页里面穿插着js部分,需要模拟一个浏览器行为,才能网页信息。对于,这部分工作,暂时,还没涉及,据说,好像有个工具叫webkit,可以解决这样的问题。这部分工作,留在以后再做吧。