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)