关键词:Python、爬虫、数据抓取、豆瓣电影,BeautifulSoup、lxml、selenium、pyhttpx
引言:
某鱼平台接到一个学生的作业单,需要获取豆瓣电影指定年份所有的电影详情用于数据分析。
代码实现主要有以下几个部分:
第一部分:抓取指定年份的票房信息
>>从票房网中获取每年的电影名称及票房
for year in range(st_y, end_y + 1, 1):
url = f'http://www.boxofficecn.com/boxoffice{year}'
res = requests.get(url)
res.encoding = res.apparent_encoding
page_text = res.text
tree = etree.HTML(page_text)
# 选取所有行
rows = tree.xpath('//tr')
# 遍历每一行
for row in rows:
columns = row.xpath('td')
if len(columns) >= 4:
box_office_text = columns[3].text
if row.xpath('.//td[2]/text()'):
movie_no = row.xpath('.//td[1]/text()')[0]
movie_year = row.xpath('.//td[2]/text()')[0]
movie_name_elem = row.xpath('.//td[3]/a/text()')
movie_name = movie_name_elem[0]
movie_url = row.xpath('.//td[3]/a/@href')[0]
# 如果上面的URL取不到则证明本身的页面并没有提供电影名称相对应的URL地址
movie_url = row.xpath('.//td[3]/h6/a/@href')[0]
# 将这一行的数据添加到结果列表中
new_results.append({"序列": movie_no,
"年份": movie_year,
"电影": movie_name,
"豆瓣链接": movie_url,
"票房": box_office_text}
)
print(f'{year}年的数据读取成功!')
第二部分、通过豆瓣搜索页找到电影的Url
因为票房网上从2015年开始列出的电影名称里就不带有A标签,所以只能从豆瓣搜索页面进行查询结果中取得。另外电影信息查询是动态JS加载,可能的话需要逆向。方便一点用Selenium来处理。
基本的代码思路如下:
options = Options()
options.add_argument('--headless') # 启用无头模式
options.add_argument('--disable-gpu') # 在某些系统中,禁用GPU加速有助于提高稳定性
options.add_argument(
'user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3') # 设置用户代理
driver = webdriver.Chrome(options=options)
url = f'https://search.douban.com/movie/subject_search?search_text={movie_name}&cat=1002'
driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
for item in soup.select('.item-root'):
title_element = item.select_one('.title-text')
link_element = item.select_one('a')
if title_element and link_element:
title = title_element.get_text()
link = link_element['href']
movies.append({'电影名称': title, '链接': link})
return movies
driver.quit()
第三部分、获取电影详情页的信息
这一部分主要是为了获取每个电影的导演、主演、和评分等信息。最后取得的数据存储在一个Json文件或者其他的持续化结构中。
cookie = '你的浏览器的Cookies'
header = {'Referer': '浏览器的Referer值',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Cookie': cookie
}
# 进行Url的Get请求,根据详情页信息利用xpath或者Bs4获得相应的项目值
# 代码就不一一展示了
出现的问题:
在测试过程连续使用python的requests库发起get或post请求返回403代码错误,使用postman发起请求发现状态码<200>竟然成功了?首先排除ip问题,ip有问题的话postman也访问不了。开始以为headers出现了问题,通过对比发现也不是headers的问题。就很奇怪 !
后来找了各种原因,原来是原生模拟浏览器 “TLS/JA3 指纹的验证”,浏览器和postman都有自带指纹验证,而唯独requests库没有。
问题解决:
使用 pyhttpx 库
安装:pip install pyhttpx
基本上可以很好的解决!
基本逻辑结构就是这样,可能在代码逻辑实现方向有一些不好的地方,也欢迎大家一起来探讨。
下面是我抓取到的结果,最终并保存CSV文件中。
目前已经抓到3000+电影数据。
有什么问题私信联系。