当前位置: 首页 > news >正文

Python 爬虫(豆瓣top250)-享受爬取信息的快乐

Python 爬虫(豆瓣top250)

一、什么是Python爬虫?

Python爬虫是一种通过模拟浏览器登录,并且抓取信息的程序,抓取的信息保证一定的价值性!

二、Python爬虫的五重架构

1. 调度器 (Scheduler)

调度器是爬虫的“大脑”和“任务中心”。它的主要职责是:

  • URL管理:维护一个待抓取URL的队列(URL Queue)和一个已抓取URL的集合(URL Set),防止重复抓取。
  • 任务分发:当下载器空闲时,从URL队列中取出一个URL,并将其分配给下载器去执行抓取任务。
  • 启动入口:接收爬虫最初的启动URL。

在简单的爬虫中,一个列表或集合就可以充当调度器。在分布式爬虫中,通常会使用像Redis这样的中间件来实现一个共享的、分布式的URL队列。

2. 下载器 (Downloader)

下载器是“体力劳动者”,负责与目标网站进行网络交互。它的职责是:

  • 获取URL:从调度器那里接收一个URL。
  • 发送请求:使用HTTP/HTTPS协议,向该URL对应的服务器发送请求(Request)。为了反反爬,这一步通常需要伪装请求头(Headers),比如User-AgentCookies等。
  • 获取响应:接收服务器返回的响应(Response),这通常是HTML、JSON或其他格式的原始数据。
  • 返回数据:将获取到的响应数据交给解析器进行处理。

常用的库requests, aiohttp, urllib

3. 解析器 (Parser)

解析器是“数据提取师”,负责从下载器返回的原始数据中提取有价值的信息。它的职责是:

  • 解析内容:接收下载器传来的响应数据(如HTML字符串)。
  • 数据提取:使用特定的解析规则(如XPath、CSS选择器、正则表达式)从页面中提取出需要的目标数据(例如:商品标题、价格、新闻内容等)。
  • URL发现:在页面中寻找新的、符合规则的URL链接,并将这些新发现的URL交给调度器,用于后续的抓取。

常用的库BeautifulSoup, lxml, PyQuery, parsel

4. 数据存储/管道 (Item Pipeline)

数据存储模块是“仓库管理员”,负责处理和保存解析器提取出的数据。它的职责是:

  • 数据清洗:对提取出的原始数据进行清洗、格式化和验证。
  • 数据持久化:将处理干净的数据保存到指定的目的地,例如:
    • 文件:CSV, JSON, XML等。
    • 关系型数据库:MySQL, PostgreSQL。
    • 非关系型数据库:MongoDB, Redis。

这个模块通常被设计成一个“管道”,数据项可以流经多个处理单元,每个单元完成一项特定的任务(如清洗、去重、存入数据库等)。

5. 爬虫引擎 (Engine)

引擎是整个爬虫系统的“心脏”和“总指挥”。它负责协调和驱动其他所有模块协同工作,控制整个系统的数据流。

  • 控制流程:启动爬虫,向调度器索要第一个URL,然后将其交给下载器。
  • 数据流转:将下载器返回的响应交给解析器,将解析器提取的数据交给数据存储管道,将解析器发现的新URL交给调度器。
  • 异常处理:处理在爬取过程中可能出现的各种异常(如请求超时、解析错误等)。
  • 并发控制:在高级爬虫框架中,引擎还负责管理并发请求,通过多线程、多进程或异步协程来提升爬取效率。

在这里插入图片描述


三、网址分析

基础网址: https://movie.douban.com/top250?start=0&filter=

规律总结

第一页:https://movie.douban.com/top250?start=0&filter=
第二页:https://movie.douban.com/top250?start=25&filter=
第三页:https://movie.douban.com/top250?start=50&filter=
...
第十页:https://movie.douban.com/top250?start=225&filter=

可以发现,每一个网页有25个电影数目,每个一页都有一个参数start=??代表从第几部电影开始!例如最后一页是:start=225,本页从第226布电影开始,到250部!所以我们只需要改变start参数的值,就可以循环访问到全部的网页。


1. 电影板块分析

在这里插入图片描述

经过分析,不难发现在此页面的中,每一个电影都有一个div class="item",所以我们要获取全部的电影列表的第一步就是将所以的class = "item"div获取下来,然后再进行更见详细的消息提取。


2. 电影名字分析

在这里插入图片描述

通过分析可以得知,每一部电影的标题一般位于一个div::hdspan行中,类为titleother,并再第一个title后面的title会带有&nbsp禁止换行的标识,在数据清洗的时候应该去掉。


3. 其余信息

在这里插入图片描述

可以发现,其余的信息:导演、演员、电影发布时间、地点、电影类型、评分、名言等,全部都位于bddiv


四、单页爬虫

1. 设置一些基本信息

Import一些必要的模块

import requests # 用于HTTP请求
from bs4 import BeautifulSoup # 用户HTML文件解析
import lxml # 提供更快的解析
import time #用于延迟访问,更像人类

设置好HTTP协议的请求头的属性

# 使用一个标准的请求头
headers = {# 用户代理,模拟不同浏览器和操作系统'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',# 接受的内容类型'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',# 接受的语言'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',# 接受的编码格式 使用HTML文件解析的时候,不要使用这个# 'Accept-Encoding': 'gzip, deflate, br',# 保持连接'Connection': 'keep-alive',# (可选) 从哪个页面跳转而来,对于防盗链的网站很重要'Referer': 'https://www.google.com/',# (可选) Cookie,处理需要登录或有用户状态的网站'Cookie': 'bid=AbmGIJqppvU; _pk_id.100001.4cf6=b4778cf8691672a8.1758706472.; __utma=30149280.652947316.1758706472.1758706472.1758706472.1; __utmc=30149280; __utmz=30149280.1758706472.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=223695111.1131007441.1758706472.1758706472.1758706472.1; __utmc=223695111; __utmz=223695111.1758706472.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __yadk_uid=1xW2nD4u1Q0yUFFSrmDKJAYI8VMuHO20; ll="118304"'
}

如果你使用了VPN,你可以添加一个设置,禁用VPN

# 禁用代理,避免网络问题
proxies = {'http': None,'https': None,
}

2. 程序主体

下面设置程序的入口main函数

# 主程序
def main():# 需要访问的网站 后面可以动态修改访问其它的页面url = r"https://movie.douban.com/top250?start=0&filter="parse_page(url)if __name__ == '__main__':main()

单页网站爬取函数

def parse_movie_info(info_div, count):try:# 获取标题# 获取info 下的所有 class 为 title 的sapntitle_spans = info_div.find_all('span', attrs={'class': 'title'})# 获取info 下的所有 class 为 other 的sapnother_span = info_div.find('span', attrs={'class': 'other'})# 获取中文名chinese_title = title_spans[0].get_text()# 获取英文名字,并且处理一些文字english_title = 'None'if len(title_spans) > 1:english_title = title_spans[1].get_text().replace('\xa0/\xa0', '').strip()# 获取别名other_title = other_span.text.replace('\xa0/\xa0', '').strip()# 获取导演与演员信息以及电影信息movie_attributes = info_div.select_one('div.bd p')# 去掉</br>if movie_attributes.br:movie_attributes.br.replace_with('|||')text = movie_attributes.get_text().replace('\xa0', '').replace('"', '')parts = text.split('|||')actors_info, attribute_info = [' '.join(part.split()) for part in parts]# 获取评分bd_div = info_div.find('div', attrs={'class': 'bd'})rating = bd_div.find('span', attrs={'class': 'rating_num'}).get_text()review_element = Nonefor span in bd_div.find_all('span'):if span.text and '人评价' in span.text:review_element = span.textreview_element = review_element.replace('人评价', '')break# 获取名言quote_element = (bd_div.find('p', attrs={'class': 'quote'}).find('span').get_text()) \if bd_div.find('p', attrs={'class': 'quote'}) else None# 存入数据save_csv([count, chinese_title, english_title, other_title,actors_info, attribute_info, rating, review_element, quote_element])print(f"----------------------- {count} -----------------------")print(f"中文名:{chinese_title} \n英文名:{english_title} \n别名:{other_title}")print(f"{actors_info}")print(f"电影信息:{attribute_info}")print(f"评分:{rating} 评价人数:{review_element}")print(f"名言:{quote_element}")print(f"-------------------------------------------------")except Exception as e:print(f"解析单个网页信息出错:{e}")
  • requests.get获取网页的响应,包括一下HTTP响应信息。

信息解析函数

def parse_page(url, page_number):try:# 获取响应response = requests.get(url, headers=headers, proxies=proxies, timeout=5)if response.status_code == 200:print(f"请求成功,开始解析第 {page_number} 页网址")# 解析响应文本,使用HTML格式soup =  BeautifulSoup(response.text, 'lxml')# 获取全部电影数目movie_list = soup.find_all('div', attrs={'class': 'item'})# 遍历每一个电影数目,获取其中的信息count = (page_number - 1) * 25 + 1for movie_item in movie_list:# 获取电影的整个信息info_div = movie_item.find('div', attrs={'class': 'info'})parse_movie_info(info_div, count)count += 1time.sleep(0.1)  # 增加一个小的延迟,模拟人类行为,是个好习惯else:print(f"请求失败!状态码:{response.status_code}")except requests.RequestException as e:print(f"请求错误:{e}")

五、多页爬虫

上面我们已经写了简单的单页爬虫,下面我们只需要完善一下功能就可以通过url的变化来爬取全部的网页了,综合代码如下(只需要修改我们的主程序):

def main():# 初始化csvcsv_init()# 循环1到10页网址for i in range(0, 10): # 所以这里的网址的start参数依次是:0,25,50...225url = 'https://movie.douban.com/top250?start=' + f'{i}' + '&filter='parse_page(url, i + 1)if __name__ == '__main__':main()

添加数据保存

def csv_init():with open('movie.csv', 'w', newline='', encoding='utf-8-sig') as csvfile:writer = csv.writer(csvfile)writer.writerow(['序号', '中文名', '英文名', '别名', '演员信息', '电影信息', '评分', '评价人数', '名言'])# 储存数据
def save_csv(info):with open('movie.csv', 'a', newline='', encoding='utf-8-sig') as csvfile:writer = csv.writer(csvfile)writer.writerow(info)

分别写入mainparse_movie_info函数中~


六、结语

如果你有其它编程语言的基础,我相信你学Python是十分的快速的,同时如果你要学习Python爬虫,你必须还要掌握一些HTML、CSS、JavaScript知识,这样的学习起来也是轻松的,同时学习一些正则表达式更加好!我也是一个小白,希望大家都可以在自己的学习道路上有所收获!

http://www.dtcms.com/a/405860.html

相关文章:

  • Kafka选举机制深度解析:分布式系统中的民主与效率
  • 一文读懂费用分析:定义、分类与成本费用区别
  • 全国做网站找哪家好做宣传海报的网站
  • 【Linux】基础IO(3)
  • 【Redis学习】Redis中常见的全局命令、数据结构和内部编码
  • AI行业应用深度解析:从理论到实践
  • AI 伦理审查破局:从制度设计到实践落地的 2025 探索
  • RocketMQ面试问题与详细回答
  • 多传感器数据融合到base_link坐标系下
  • 阿里新开源Qwen3-Omni技术解析
  • Flink 流式分析事件时间、Watermark 与窗口
  • 解析前端框架 Axios 的设计理念与源码
  • 使用IOT-Tree消息流InfluxDB模块节点实现标签数据的时序数据库存储
  • 【深入理解JVM】垃圾回收相关概念与相关算法
  • 文档抽取技术:金融保险行业数字化转型的核心驱动力之一
  • 神秘魔法?耐达讯自动化Modbus TCP 转 Profibus 如何为光伏逆变器编织通信“天网”
  • 做庭院的网站佛山网站专业制作
  • wordpress开启多站点营销云官网
  • 企业AI 智能体(AI_Agent)落地开源方案:Dify、n8n、RAGFlow、FastGPT、AutoGen和OAP深度梳理与对比分析
  • Day51 时钟系统与定时器(EPIT/GPT)
  • Django 搭配数据库开发智慧园区系统全攻略
  • 前端基础知识---10 Node.js(三)
  • article.3345645398
  • 国内如何使用GPT-5-Codex
  • Xcode 26 could not locate developer disk image for this device 无法定位开发者磁盘镜像
  • 用Python打造离线语音控制浏览器:基于VOSK的实用案例
  • 【ARDUINO】在arduino ide中下载安装开发包失败了,如何手动安装开发包
  • 上架 App 全流程解析,iOS 应用上架步骤、App Store 审核流程、ipa 文件上传与测试分发经验
  • 网站审核要多久老铁外链
  • 网站建设公司的服务公司湖南做网站 在线磐石网络