使用Python爬取豆瓣TOP250并存入csv文件

2022年12月16日 14:26 阅读 2.4k 评论 0

几个月以前在B站发布了几个教程视频,其中使用Python爬取豆瓣TOP250并存入csv文件目前最受欢迎,好多小伙伴也问我要源码,本来准备同步到github的,但是想想直接给源码的方式不利于学习,所以我准备将之后的教程视频发布后再在博客同步发一篇教程视频。

废话不多说,进入正题。

本文用到了Python的requests和lxml库,浏览器插件XPath Helper ,请提前下载安装好。

一、观察网页结构以及拉取数据的方式

我们在爬取一个网页时,首先要对网页元素的布局以及数据的拉取方式进行分析。

我们按下F12(部分电脑需要按下fn+f12),然后刷新页面观察xhr处有没有发起ajax请求。

刷新后,xhr为空,代表网页的数据来自于服务器渲染,我们需要从网页源代码中去提取数据。

二、提取网页数据

提取数据的方式很多,有时候可以混合使用,这里我们使用xpath就可以解决所有的需求。

我们在开发者工具中点击左上角小箭头,然后点击你想爬取的信息,即可自动定位

我们在定位后的dom结构中找到一个全局唯一的父元素,可以是class_name,也可以是id。

比如上图中的图片链接的xpath我就可以写为

//ol/li/div/div[@class='pic']/a/img/@src

同时我们发现img标签的alt属性是包含电影名称的,所以我们也可以通过alt获取电影的名称。

其他的信息获取方法都是类似的,多试几次就行,这里不再赘述。

获取信息的代码如下:

headers = { 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 
} 


def get_html(start): 
    url = f'https://movie.douban.com/top250?start={start}&filter=' 
    response = requests.get(url, headers=headers) 
    print(response.status_code) 
    html = etree.HTML(response.text)  # 将网页字符串转换为element对象 
    movie_lis = html.xpath("//ol/li") 
    for li in movie_lis: 
        title = ''.join(li.xpath("div/div[@class='info']/div[@class='hd']/a/span[1]/text()")) 
        description = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p/text()")).replace('\n', '').replace(' ', '') 
        rating = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()")) 
        comment_num = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[4]/text()")) 
        quote = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p[@class='quote']/span/text()")) 
        cover = ''.join(li.xpath("div/div[@class='pic']/a/img/@src")) 

其中,headers是用来防反爬的,具体原理可以在搜索引擎自行搜索了解。

此外,我们点击底部的翻页,发现每页只有start参数在变化,每次增加25,所以采取循环的方式来爬取所有的数据

三、保存数据

我们已经获取到了数据,剩下就是保存了,保存的方式也很多,txt、csv、excel、数据库等等都可以,这里采用pythoner最常用的csv格式。 csv与excel观感上并无不同,只是更利于程序写入,一个半角逗号隔开代表是一列,每一行最后写入一个\n表示本行结束,由这个规则我们可以写出保存数据的函数。如下:

def save_data(title, description, rating, comment_num, quote, cover): 
    movie_info = f'{title},{description},{rating},{comment_num},{quote},{cover}\n' 
    fp.write(movie_info) 

完整代码

import requests 
from lxml import etree 

headers = { 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" 
} 


def get_html(start): 
    print('正在爬取', start) 
    url = f'https://movie.douban.com/top250?start={start}&filter=' 
    response = requests.get(url, headers=headers) 
    print(response.status_code) 
    html = etree.HTML(response.text)  # 将网页字符串转换为element对象 
    movie_lis = html.xpath("//ol/li") 
    for li in movie_lis: 
        title = ''.join(li.xpath("div/div[@class='info']/div[@class='hd']/a/span[1]/text()")) 
        description = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p/text()")).replace('\n', '').replace(' ', '') 
        rating = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()")) 
        comment_num = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/div[@class='star']/span[4]/text()")) 
        quote = ''.join(li.xpath("div/div[@class='info']/div[@class='bd']/p[@class='quote']/span/text()")) 
        cover = ''.join(li.xpath("div/div[@class='pic']/a/img/@src")) 
        save_data(title, description, rating, comment_num, quote, cover) 


def save_data(title, description, rating, comment_num, quote, cover): 
    movie_info = f'{title},{description},{rating},{comment_num},{quote},{cover}\n' 
    fp.write(movie_info) 


if __name__ == '__main__': 
    fp = open('./豆瓣TOP250.csv', 'a+', encoding='utf-8-sig') 
    head = '名称,简介,评分,评论人数,引言,封面图\n' 
    fp.write(head) 
    for start in range(0, 250, 25): 
        get_html(start) 
    fp.close() 

代码整体比较简单,如果有疑问可以在评论区提出。

最后修改于2022年12月16日 14:29
©允许规范转载

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:https://www.yangyingqi.com/60.html

Python 爬虫
微信
支付宝
登录后即可进行评论/回复