美文网首页
Python豆瓣爬虫学习笔记(六)

Python豆瓣爬虫学习笔记(六)

作者: 瓦力求索 | 来源:发表于2015-03-21 00:20 被阅读168次

    一周没有更新了,在阅读crossin.me中jxgx072037写的代码时发现不懂的地方太多,一点点啃下来花费了不少时间,不过收获不少,但还没有对class def dic有进一步的了解,后期再慢慢吸收吧。在他代码的基础上进行了简单修改,也可以正常运行,先把代码贴上,比较好的技巧都在注释中提到了:

    # -*- coding: cp936 -*-

    import urllib2

    import re

    import time

    f=urllib2.urlopen('http://movie.douban.com/tag/?view=type').read()#抓取tag

    n1=f.find('/h2')#定位抓取位置头

    n2=f.find('2015')#定位抓取位置尾

    f1=f[(n1-4):(n2+10)]#定位抓取范围

    f2=re.findall('/\S{1,}"',f1)#初步抓取tag

    f3=''.join(f2)#转为str,方便后面replace

    f4=f3.replace('"','')#去除杂质

    movie_tags=f4.split('/')#转为list,方便后面[]

    del movie_tags[0]#

    #print len(movie_tags)

    #print movie_tags

    class Movie_list:#建立Movie_list类,方便后面引用

    def __init__(self):#

    self.url1='http://movie.douban.com/tag/'#

    def request_open(self,n1,n2):#为提取文本定义函数request_open,n1为tag,n2为页数

    self.url2='?start='+str(n2*20)+'&type=T'#n2*20是通过观察页面得出规律,url后半段,方便拼接url

    self.page1=urllib2.urlopen(self.url1+movie_tags[n1]+self.url2).read()#将url1、tag、url2三部分拼接起来,提取每个页面的电影信息

    return self.page1#将self.page1值返回给request_open

    class Next_page:#

    def __init__(self):#

    self.url1='http://movie.douban.com/tag/'#

    def np(self,n1):#为提取页面数定义函数np,n1为tag

    self.page1=urllib2.urlopen(self.url1+movie_tags[n1]).read()#将url1、tag两部分拼接起来,提取每个tag的信息

    self.url2=re.findall('type=T.*\d{1,2}',self.page1)#从tag中提取该tag的标签页

    #print self.url2[-1]

    #print self.url2[-1][9:]

    if self.url2:#if为self.url2筛选值,如果为真值,则进下以下步骤

    self.num2=self.url2[-1][9:]#取出杂质,self.url2为list,[-1]取最后一个值,[9:]提取单独的页码值,非常简洁的提取方式

    #print self.num2

    if int(self.num2)<10 or int(self.num2)==10:#通过最后一个页面数进行判断是否大于10页

    return int(self.num2)#如果不大于10页,就全部提取

    else:#大于10页

    return 10#就赋值10.只提取10页

    #print self.num2

    else:#如果self.url2为False

    return 1#则赋予值1

    #print self.num2

    movie_list=Movie_list()#实例MOvie_list()

    movie=[]#建立空list,方便后面append

    class Movie_info:

    def __init__(self):

    pass

    def m(self,n1,n2):#定义m函数提取movie信息,n1为tag值 n2为页码值

    self.movie_name2=[]#电影名空list

    self.movie_name1=re.findall('title="\S{1,}?"',movie_list.request_open(n1,n2))#初步提取所有页面的电影名,

    for x in range(len(self.movie_name1)-1):#循环读取

    self.movie_name2.append(self.movie_name1[x][7:-1])#去除杂质,添加到list

    #print self.movie_name1[x][7:-1]

    self.movie_comment2=[]#电影评论人数空list

    self.movie_comment1=re.findall('\(\d{1,}.*?\)|\(\xe5\xb0\x9a\xe6\x9c\xaa\xe4\xb8\x8a\xe6\x98\xa0\)|\(\xe7\x9b\xae\xe5\x89\x8d\xe6\x97\xa0\xe4\xba\xba\xe8\xaf\x84\xe4\xbb\xb7\)|\(\xe5\xb0\x91\xe4\xba\x8e10\xe4\xba\xba\xe8\xaf\x84\xe4\xbb\xb7\)|\(\xe8\xaf\x84\xe4\xbb\xb7\xe4\xba\xba\xe6\x95\xb0\xe4\xb8\x8d\xe8\xb6\xb3\)',movie_list.request_open(n1,n2))

    for s in self.movie_comment1:#循环读取

    #print s

    if re.findall('\d{1,}',s):#初步提取页码值

    #print re.findall('\d{1,}',s)[0]

    self.movie_comment2.append(re.findall('\d{1,}',s)[0])#去除杂质

    else:

    self.movie_comment2.append('0')

    #print self.movie_comment2

    #提取评分信息

    self.movie_rating2=[]

    self.movie_rating1=re.findall('class=\"star clearfix[\s\S]*?pl',movie_list.request_open(n1,n2))

    for s in self.movie_rating1:

    self.p2=re.findall('\d\.\d',s)

    if self.p2:

    self.movie_rating2.append(self.p2[0])

    else:

    self.movie_rating2.append('没有评分')

    #提取电影URL

    self.movie_url2=[]

    self.n=0

    self.movie_url1=re.findall('http://movie.douban.com/subject/\d{1,10}',movie_list.request_open(n1,n2))

    for i in range(len(self.movie_url1)/2):

    self.movie_url2.append(self.movie_url1[2*self.n])

    self.n+=1

    #将提取到的信息添加到dic中

    for i in range(len(self.movie_name2)):

    self.dic=[]

    self.dic.append(self.movie_name2[i])

    self.dic.append(self.movie_comment2[i])

    self.dic.append(self.movie_rating2[i])

    self.dic.append(self.movie_url2[i])

    #self.dic[1]代表comment,评论人数大于50000的记录,不到的不记录

    if int(self.dic[1])>50000:

    movie.append(self.dic)

    #电影名进行排重

    if len(movie)>2:

    for i in range(len(movie)-1):

    #如果最新添加的电影名同原来记录中的任意一项相同

    if movie[-1][0]==movie[i][0]:

    #print moive[-1]

    #删除最新添加的,即去重

    del movie[-1]

    #去重后 中止循环

    #break

    print '%d/3000'%(len(movie))

    else:

    continue

    next_page=Next_page()

    movie_info=Movie_info()

    for x in range(len(movie_tags)-130):#循环标签,为减少工作量,仅抓取7个标签,len(movie_tags)=137

    print'正在抓取标签"%s"中的电影,%d/%s'%(movie_tags[x],x+1,len(movie_tags)-130)#查看抓取记录

    starttime2=time.time()#起始时间

    for i in range(next_page.np(x)):#循环页面

    print'开始抓取第%d页,抓取进度:'%(i+1)

    starttime=time.time()

    movie_info.m(x,i)#将标签值、页面值赋予m函数

    endtime2=time.time()

    print'抓取第%d页完毕,用时%.2fs'%(i+1,endtime2-starttime2)

    #time.sleep(5)

    endtime2=time.time()

    print '抓取"%s"标签完毕,%d/%s,用时%.2fs\n'%(movie_tags[x],x+1,len(movie_tags)-130,endtime2-starttime2)

    '''if len(movie)>100:

    print len(movie)

    for i in range(len(movie)-100):

    print i

    print len(movie)-100

    print movie[-i]

    del movie[-i]

    '''

    def comment(s):

    return int(s[1])

    starttime4=time.time()

    print'开始排序……'

    movie.sort(key=comment,reverse=True)

    endtime4=time.time()

    print'排序完毕,共耗时%.2f'%(endtime4-starttime4)

    f=file('Douban_movies.html','w')#创建并打开html

    #html头

    f.write('\n\n\n')

    f.write('\n')

    f.write('\n\n\n')

    f.write('

    豆瓣电影榜单

    '+' '+'

    按评价人数排名

    ')

    s=1

    for i in movie:

    f.write('

    '+str(s)+'. '+''+i[0]+''+',共'+i[1]+'人评价,'+'得分:'+i[2]+'分;'+'\n')

    s+=1

    f.write('')

    f.close

    print'完成!请查看html文件,获取豆瓣电影榜单。'

    豆瓣爬虫学习,先告一段落,自己接下来会随意在网上找个小网站实践抓取下,这样对理解爬虫会有更有帮助

    相关文章

      网友评论

          本文标题:Python豆瓣爬虫学习笔记(六)

          本文链接:https://www.haomeiwen.com/subject/bswwxttx.html