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 尝试对豆瓣上的演员参演电影的电影名和上映日期进行抓取的主要内容,如果未能解决你的问题,请参考以下文章

豆瓣上映电影爬虫

.利用python获得豆瓣电影前30部电影的中文片名,排名,导演,主演,上映时间

对豆瓣电影进行可视化分析

对豆瓣电影近十年数据进行分析分析(截止2019年3月)

团队-爬取豆瓣电影TOP250-需求分析

团队-爬取豆瓣电影TOP250-需求分析