基于 Airflow 调度的爬虫系统

2022/08/15 Python 共 2134 字,约 7 分钟
欢迎

从 0 到 1 搭建及优化针对某网站信息的爬虫系统,并使用 Airflow 调度任务。

对于所涉及技术点的基本使用,本文不展开讲解,仅记录关键点和难点。源码可以参阅 GitHub

系统介绍

整体项目通过 Docker 部署,流程大致分为以下步骤:

  • 爬取网站信息,每日一次
  • 写入 MySQL 数据库
  • 进行数据分析,通过 e-mail 和钉钉发送给指定收件人

爬虫部分

常见的爬虫实现方式有 requests、selenium、scrapy 等。其中 selenium 的原理是模仿真实浏览器的浏览过程,且可多样定制化,比较适合本次爬取频率较低的需求,故而选择。

定制化

由于将来要部署在 Ubuntu 系统的服务器上,考虑性能、反爬等诸多因素,需要额外设置浏览器的参数,主要包括无头、无图、窗口大小、UA、无自动化标识等。

options.add_argument('--headless')
options.add_argument('--blink-settings=imagesEnabled=false')
options.add_argument('--window-size=1920,1080')
options.add_argument('user-agent=%s' % UserAgent().random)
options.add_experimental_option('excludeSwitches', ['enable-automation'])

另外的重要反扒手段有 cookies 登录以及设置代理等。其中前者可以在有界面浏览器登录后存储,后续使用时加载即可。

driver = webdriver.Chrome()
driver.get('your_url')
time.sleep(60)  # log in manually within 60 seconds
dict_cookies = driver.get_cookies()
json_cookies = json.dumps(dict_cookies)
# sava into local file
with open("your_file_name", "w") as f:
    f.write(json_cookies)
driver.close()

代理方面选择了开源免费的 Proxy Pool,可以直接使用 Docker 部署。不过实测可用的代理较少(毕竟免费),且目标网站对使用了代理后的访问似乎仍然能够识别(表现为更换 IP 后仍然提示访问异常),因此总体效果不佳。

无头浏览器安装

初始尝试参考网上的一些教程手动安装,为保证浏览器和驱动的版本兼容性,需要手动下载二者相互匹配的安装包,然后在 Dockerfile 文件中指定复制文件并安装。

COPY ./resources .
USER 0
RUN apt-get update
RUN apt-get install -y ./google-chrome-stable_current_amd64.deb
RUN rm google-chrome-stable_current_amd64.deb
RUN mv -f chromedriver /usr/local/share/chromedriver
RUN ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
USER 50000
# check version
google-chrome --version
chromedriver --version

后来遇到过一次提示无法安装成功的错误(仍然是依赖问题),加之该过程较为繁琐,因此后来改为了直接在 Dockerfile 文件中通过 apt-get 命令在线安装浏览器。

RUN apt-get install -y chromium

而驱动则使用 WebDriverManager 解决,详细使用方法可见官方文档

另外可通过访问下方网址,简单测试无头浏览器的伪装程度。

driver.get('https://intoli.com/blog/not-possible-to-block-chrome-headless/chrome-headless-test.html')

数据库交互

此部分可参考之前发的一篇博文。除文中所述,Airflow 自带的 MySQLConnector 也是与数据库交互的可选方式之一。

另外,Airflow 提供了很好的存储功能,可以保存包括数据库连接信息在内的诸多变量信息,因此非爬虫部分的配置信息多数选择直接存储在其中(爬虫部分为方便调试存储在配置文件中)。

调度部分

如上所属,通过 Docker 环境,使用 Airflow 进行调度(爬虫与 Airflow 调度系统均使用 Python 语言)。

发送信息

将简单分析后的数据通过 e-amail 和钉钉,发送给指定收件人。仿照钉钉原理,微信/飞书等平台也可以实现,具体可参考网络相关资料。

e-mail

e-mail 的实现方式较为普遍和简单,根据官方文档使用即可。值得注意的是添加附件时,分布式调度系统应注意附件文件和任务要运行在同一台主机上,此处参考了 Github 上的样例

钉钉

在 Airflow 早期版本中,发送钉钉消息功能需要参照 e-mail 机制,自己修改一下源码。较新版本中官方也支持了钉钉消息,参考相关博文及官方文档即可实现。

文档信息

Search

    Table of Contents