《Python爬虫实战:抓取某瓣电影信息与票房数据分析》

关键词: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+电影数据。

有什么问题私信联系。

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值