zoukankan      html  css  js  c++  java
  • 2-1 用Python尝试对豆瓣上的演员参演电影的电影名和上映日期进行抓取

     1 step1_actorsDate.py
     2 # -*- coding: utf-8 -*-
     3 import requests
     4 import pandas as pd
     5 import lxml.html
     6 import time
     7 from pandas import DataFrame
     8 
     9 headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
    10 def getDoc(url):
    11     resp=requests.get(url,headers=headers)
    12     time.sleep(1)
    13     content=resp.text
    14     doc = lxml.html.fromstring(content)
    15     return doc
    16 
    17 def getactorUrl(doc,url_oneMovie):
    18     leadingRoles=doc.xpath('//*[@id="info"]/span[3]/span[2]/a/text()')
    19     actorUrl=doc.xpath('//*[@id="info"]/span[3]/span[2]/a/attribute::href')
    20     if leadingRoles==[]:
    21         leadingRoles=doc.xpath('//*[@id="info"]/span[2]/span[2]/a/text()')
    22         actorUrl=doc.xpath('//*[@id="info"]/span[2]/span[2]/a/attribute::href')
    23     for i in range(len(leadingRoles)):
    24         leadingRoles[i]=unicode(leadingRoles[i]).encode('utf-8')
    25     return leadingRoles,actorUrl  #返回的是list
    26 
    27 leadingRoles=[]
    28 actorUrl=[]
    29 
    30 df=pd.read_csv('doubanIMDB_data_final.csv')
    31 urllist=df['url']
    32 startPoint=995
    33 for i in range(startPoint-1,len(urllist)):
    34     try:
    35         print i+1
    36         url=urllist[i]
    37         doc = getDoc(url)
    38         temp1,temp2= getactorUrl(doc,url)  #temp1和temp2分别是主演和主演对应的链接
    39         leadingRoles=leadingRoles+temp1
    40         actorUrl=actorUrl+temp2
    41     except:
    42         print 'Error'
    43     finally:
    44         df_actor = DataFrame({'leadingRoles': leadingRoles, 'actorUrl': actorUrl})
    45         df_actor.to_csv('test.csv', index=False)
     1 step2_getUrl.py
     2 # -*- coding: utf-8 -*-
     3 '''
     4 该脚本的功能仅仅是将actorUrl列中的每一项转化成网页链接
     5 并去重
     6 '''
     7 import pandas as pd
     8 df=pd.read_csv('actors.csv')
     9 print len(df)
    10 df.drop_duplicates()  #去重
    11 print len(df)
    12 for i in range(len(df)):
    13     df.ix[i,'actorUrl']='https://movie.douban.com'+df.ix[i,'actorUrl']
    14 df.to_csv('actors_unique.csv',index=False)
     1 step3_searchToUrl.py
     2 # -*- coding: utf-8 -*-
     3 '''
     4 actorDate.py得到的演员及其对应网站的数据中,有些并不是演员的主页网址,
     5 而是在豆瓣上搜索该演员的页面
     6 该脚本的作用就是通过演员的搜索页面得到该演员的主页网址
     7 '''
     8 import requests
     9 import pandas as pd
    10 import lxml.html
    11 import time
    12 from pandas import DataFrame
    13 
    14 headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
    15 def getDoc(url):
    16     resp=requests.get(url,headers=headers)
    17     time.sleep(1)
    18     content=resp.text
    19     doc = lxml.html.fromstring(content)
    20     return doc
    21 
    22 def searchToUrl(searchPage):
    23     doc = getDoc(searchPage)
    24     #此处用的是attribute属性,得到的是属性中的href属性
    25     temp = doc.xpath('//*[@id="content"]/div/div[1]/div[1]/div/div[2]/h3/a/attribute::href')
    26     #如果得不到演员的主页网址,则返回withoutHomePage
    27     if temp==[]:
    28         temp = ['withoutHomepage']
    29     actorUrl = temp[0]
    30     return actorUrl
    31 
    32 df=pd.read_csv('actors_unique.csv')
    33 errorNum=0  #统计页面中为搜索页面的个数
    34 for i in range(len(df)):
    35     temp=df.ix[i,'actorUrl']
    36     if 'search' in temp:  #如果网址中含有'search'字样,则说明该网址为豆瓣电影中该演员的搜索页面
    37         #需要进行修正,将该搜索页面修改为演员的主页
    38         errorNum+=1
    39         temp=searchToUrl(temp)  #调用searchToUrl函数,返回的是演员主页
    40         print '已修正'+str(errorNum)+'个页面!'  #作为标记
    41         print '修改为:',temp  #作为标记
    42         df.ix[i,'actorUrl']=temp  #将搜索页修改为演员主页
    43 
    44 #对修改之后的数据进行错误统计
    45 errorNumAfter=0
    46 for i in range(len(df)):
    47     temp=df.ix[i,'actorUrl']
    48     if 'search' in temp:
    49         errorNumAfter+=1
    50 print '修改后的错误个数为:',errorNumAfter
    51 
    52 #将修改后的数据输出到文件中
    53 df.to_csv('actors_correct.csv',index=False)
     1 step4_getWorks.py
     2 # -*- coding: utf-8 -*-
     3 import requests
     4 import time
     5 import lxml.html
     6 import re
     7 from pandas import DataFrame
     8 import pandas as pd
     9 import random
    10 
    11 headers = {"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
    12 proxies={'http':'http://190.195.170:8080'}
    13 # cookies = dict(cookies_are='working')
    14 # ,cookies=cookies
    15 # ,proxies=proxies
    16 def getDoc(url):
    17     resp=requests.get(url,headers=headers)  #得到网页响应
    18     print resp.status_code
    19     timegap=random.random()*5
    20     time.sleep(timegap)   #暂停1秒,防止抓取太频繁被封IP
    21     content=resp.text  #获取相应内容
    22     doc = lxml.html.fromstring(content)
    23     return doc
    24 
    25 
    26 #函数:将形如(2016)的形式转换成int格式的2016
    27 #并返回int格式的2016
    28 def toInt(dateOfMoviesList):  #注意处理对象为list列表
    29     reYear = re.compile('((d*))')  #编译待匹配字符串
    30     for i in range(len(dateOfMoviesList)):
    31         temp=re.findall(reYear,dateOfMoviesList[i])  #对每一项进行匹配
    32         if temp!=[]:  #有些演员演过的电影没有标注上映日期,所以需要做非空判断
    33             dateOfMoviesList[i]=int(temp[0])
    34         else:
    35             dateOfMoviesList[i]=99999999
    36     return dateOfMoviesList
    37 
    38 df=pd.read_csv('step3_actors_correct.csv')
    39 actorMovies=[]  #初始化演员演过的电影的列表
    40 yearOfFirstMovie=[]  #初始化演员出道年份列表,此处将演员演过的最老电影的年份作为他的出道年份
    41 moviesNum=[]  #初始化演员演过的电影数的列表
    42 errorNum=1  #对出错数进行计数
    43 for k in range(1197,len(df)):
    44     url_actor=df.ix[k,'actorUrl']  #取出每个演员的主页网址
    45     print df.ix[k,'leadingRoles']
    46     try:
    47         if url_actor!='withoutHomepage':  #由于有些演员没有主页,所以此处进行判断
    48             i=0  #用于内层循环
    49             temp1=[1]  #冷启动
    50             moviesOfActorList=[]  #初始化某一个演员演过电影的列表,每一次循环都要初始化一次
    51             dateOfMoviesList=[]  #初始化某一个演员演过电影对应日期的列表,此处是形如'(2016)'的形式
    52             while(temp1!=[]):  #当可以抓取到内容时,不停循环
    53                 url_moviesOfActor=url_actor+'movies?sortby=time&format=pic&start='+str(i*10)  #根据网址规律得到
    54                 doc=getDoc(url_moviesOfActor)
    55                 temp1=doc.xpath('//*[@id="content"]/div/div[1]/div[2]/ul/li/dl/dd/h6/a/text()')
    56                 moviesOfActorList+=temp1   #将每个页面的得到的电影列表加入到该演员演过电影的列表中
    57                 temp2=doc.xpath('//*[@id="content"]/div/div[1]/div[2]/ul/li/dl/dd/h6/span[1]/text()')
    58                 dateOfMoviesList+=temp2  #同理
    59                 i+=1  #用于内层循环
    60             dateOfMoviesList=toInt(dateOfMoviesList)  #调用toInt函数,将得到的年份字符串转换为int数据类型
    61             yearOfFirstMovie.append(min(dateOfMoviesList))  #演员出道年份,即演员演过的第一部电影,就是所有该演员演过电影的年份最小的那一个
    62             #######################################
    63             # 未解决
    64             # 对演员演过的电影名字列表进行格式转换
    65             # for i in range(len(moviesOfActorList)):
    66             #     print moviesOfActorList[i]
    67             #######################################
    68             temp={'moviesOfActor':moviesOfActorList,'dateOfMovies':dateOfMoviesList}  #将演员演过的电影及电影的日期转换成字典
    69             actorMovies.append(temp)  #将上述字典作为一项,不停加入到演员演过的电影列表中
    70             moviesNum.append(len(moviesOfActorList))  #将演员演过的电影的数量,不停加入到演员演过的电影数量列表中
    71         else:  #如果该演员没有豆瓣主页,则分别向列表中加入下面三项
    72             actorMovies.append('withoutHomepage')
    73             yearOfFirstMovie.append('unknown')
    74             moviesNum.append('unknown')
    75     # except:  #如果出错,进行如下处理
    76     #     actorMovies.append('error')
    77     #     yearOfFirstMovie.append('error')
    78     #     moviesNum.append('error')
    79     #     print 'error,No.',errorNum
    80     #     errorNum+=1  #错误数量统计
    81     finally:
    82         print k+1  #做标记使用
    83         df1=DataFrame({'actorMovies':actorMovies,'yearOfFirstMovie':yearOfFirstMovie,'moviesNum':moviesNum})
    84         df1.to_csv('test.csv',index=False)
  • 相关阅读:
    存储过程的语法
    C#之理解接口的作用
    获取gridview模板列里面的控件的ID
    asp.net asp:Repeater嵌套绑定方法(2)
    asp.net asp:Repeater嵌套绑定方法(1)
    listview 绑定hashtable 以及值的显示
    mark
    程序员的路该怎么样继续走下去?
    多条件查询以及分页存储过程(倒叙和顺序查询)
    发生ActionScript 错误:[RPC Fault faultString="发送失败" faultCode="Client.Error.MessageSend" faultDetail="Channel.Connect.Failed
  • 原文地址:https://www.cnblogs.com/PistonType/p/5499047.html
Copyright © 2011-2022 走看看