2-1 尝试对豆瓣上的演员参演电影的电影名和上映日期进行抓取
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2-1 尝试对豆瓣上的演员参演电影的电影名和上映日期进行抓取相关的知识,希望对你有一定的参考价值。
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)
以上是关于2-1 尝试对豆瓣上的演员参演电影的电影名和上映日期进行抓取的主要内容,如果未能解决你的问题,请参考以下文章