- BeautifulSoup: 用于解析网页和提取数据的库。
- Playwright: 实现浏览器自动化,用于获取动态网页内容。
- Requests: 用于发送网络请求,获取网页数据。
- PyYAML: 用于读取和解析 YAML 配置文件。
- 代理池: 用于获取可用的代理 IP,增加访问的隐匿性和稳定性。
- 文件操作: 用于记录爬虫的状态和日志信息,方便后续维护和调试。
- CSV 文件解析: 用于读取和解析 CSV 格式的文件,获取城市和区域信息。
- 时间随机等待: 在访问网页或发送请求之间引入随机等待时间,以模拟人类的操作行为,减小被网站检测到的风险。
- 启动程序,读取 YAML 配置文件,连接 MySQL 数据库,并创建 jobs 表。
- 读取 CSV 文件,获取城市和区域 ID。
- 使用 Playwright 控制 Firefox 浏览器,构造 URL 访问职位列表页。
- 如果访问失败,根据配置的重试次数进行重试,并在多次失败后重新启动浏览器。
- 成功访问页面后,使用 BeautifulSoup 解析页面,提取 Job 卡片信息。
- 关闭浏览器和页面,删除使用的代理。
- 将 Job 信息插入 MySQL 数据库的 jobs 表。
- 记录成功导入的行数和城市 ID,下次启动时从该点继续。
- 读取 config.yaml 文件,获取 MySQL 配置信息。
- 连接到 MySQL 数据库,并创建 jobs 表。
- 为 jobs 表的各列添加注释。
- 提交修改,并关闭数据库连接。
- 读取 YAML 配置文件,连接到 MySQL 数据库。
- 创建 jobs 表,用于存储职位信息。
- 为 jobs 表添加注释。
- 读取 CSV 文件,逐行构建 INSERT SQL 语句。
- 执行 SQL 语句,将职位信息插入数据库。
- 提交事务,并关闭数据库连接。
- 读取最后一次成功导入的行号和城市 ID,作为本次导入的起点。
- 打开 CSV 文件,逐行读取数据。
- 如果行号小于等于最后一次成功导入的行号,跳过该行。
- 根据行内容获取城市 ID 和区域 ID。
- 调用 get_html() 方法获取该城市和区域的职位信息。
- 将获取的职位信息保存到 MySQL 数据库。
- 更新最后一次成功导入的行号和城市 ID。
- 随机等待一段时间,避免请求过快。
- 读取配置文件,获取 Debug 等配置信息。
- 获取代理。
- 使用 Playwright 控制 Firefox 浏览器。
- 构造职位页面 URL,循环访问页面。
- 如果访问失败,根据配置的重试次数和超时时间进行重试。
- 如果多次重试仍然失败,重新启动浏览器。
- 成功访问页面后,使用 BeautifulSoup 解析页面,提取 Job 卡片信息。
- 关闭浏览器和页面。
- 删除使用的代理。
-
从 BeautifulSoup 对象中查找第一个 job-card-wrapper 元素,作为一个 Job 卡片。
-
提取该卡片的详细信息,包括职位链接、职位名称、地点、薪资、标签和公司名称。
-
将一个 Job 卡片的信息添加到 job_cards 列表。
-
找到下一个 job-card-wrapper 元素,重复步骤 2-3。
-
返回 job_cards 列表。
本项目基于以下技术栈实现了强大的反爬机制,稳定地抓取目标网站的数据:
- Playwright 实现浏览器自动化:使用 Playwright 库启动 Firefox 浏览器,实现对动态网页的自动化抓取。通过模拟真实浏览器行为,绕过一些基于用户代理的反爬机制。
- 动态代理与代理池:通过本地代理池 API 获取和删除代理,实现动态代理的使用。当访问页面失败时,自动更换代理,并重试访问,提高了抗封禁能力和稳定性。
- 随机等待策略:引入随机等待策略,模拟真实用户的访问行为。在访问每个页面后,随机等待一段时间,减少请求频率,降低被网站检测到的风险。
- 可配置的重试次数和超时时间:通过 YAML 配置文件设置重试次数和超时时间等参数。可灵活调整重试策略,增加反爬的难度。
- 增量更新:记录最后成功抓取的页面,实现增量更新的功能。避免重复抓取,提高效率。
- 强大的失败重试机制:当访问页面失败时,本项目具有强大的重试机制。根据配置的最大重试次数,爬虫会自动尝试重新访问页面。若多次重试仍然失败,则采取以下措施:
- 代理更换与浏览器重启:爬虫会删除当前使用的代理,并获取一个全新的代理进行访问。如果仍然无法成功,将完全重新启动浏览器,获取新的代理,并再次访问目标页面。
- 随机等待:在获取每个代理和重启浏览器后,爬虫会随机等待一定时间再继续访问。这使得网站难以检测到失败重试的模式,减小了被检测为爬虫的可能性。
-
增加并发能力:目前的爬虫是单线程执行的,可以考虑使用异步编程框架(如 asyncio)或多线程/多进程技术来提高并发能力,从而加快数据抓取速度。
目前由于项目需求采用单线程进行爬取,如果要使用多线程需要考虑几个问题:
- 爬取任务分配
- ip 池容量
- 增量同步
- 需求分析(是否有多线程需求,单个网址多线程更容易触发反爬)
-
使用更稳定的代理:当前项目使用代理池获取代理 IP,可以进一步改进代理池的质量和稳定性,确保获取到的代理 IP 可靠且高效,提高反爬能力。
这个只能说,钱到位了都好说。付费代理肯定比免费的香。
-
支持更多的网站和数据源:可以扩展爬虫的功能,支持抓取更多不同类型的网站和数据源,提供更广泛的数据来源。
这部分只要在parse.py中添加对应解析即可,然后在get——html中写上对应方案。
-
引入分布式架构:考虑将爬虫项目改造为分布式架构,通过多台机器并行执行任务,提高整体的抓取效率和容错能力。
由于本身项目只是一个课程作业,因此尚未考虑。且个人服务器资源不足。
-
完善错误处理和日志记录:进一步优化爬虫的错误处理机制,增加对异常情况的处理,如网络连接中断、页面解析错误等,并加强日志记录功能,方便排查问题和进行监控。
后续会进行改进,在日志处理上进行打磨。
-
增加数据清洗和处理功能:可以在数据抓取后进行数据清洗、去重、格式转换等处理,确保数据的质量和准确性。
这部分请看另外一个项目
-
引入机器学习和自动化技术:利用机器学习算法对爬取的数据进行分析和挖掘,自动化处理某些任务,如职位分类、关键词提取等,提供更智能化的数据处理功能。
学习成本较高,且目前爬取网址的反爬尚未需要到此程度。
-
增强安全性和稳定性:加强爬虫的安全性,确保对目标网站的访问和数据抓取符合法律和道德规范,同时增强爬虫的稳定性,提高其长时间运行的可靠性。
本项目仅为学习,为校内课程作业,不会将数据用于任何商业用途。
谨记:爬虫写的好,牢房吃到老。
- 字符集要注意,建议用 utf8mb4