10分钟上手搭建爬虫服务

作者: 小连清Sunny | 来源:发表于2017-12-25 14:10 被阅读0次

本文由博主最初发布于华为开发者社区,原地址:https://portal.huaweicloud.com/blogs/46c0ffaad0ee11e7b8317ca23e93a891,再次感谢华为对文章的认可与鼓励 😂

爬虫是时下十分热门的一种程序,谷歌、百度等搜索引擎以及今日头条、即刻等热门应用均建立在爬虫程序的基础上,构成互联网巨大流量的入口。那么现代的爬虫是如何工作,我们自己又如何借助华为云服务搭建自己的爬虫呢?下面我们以爬取华为开发者社区所有的博客为例,利用时下热门的 PySpider 框架快速搭建一个基本的爬虫服务。

爬虫的基本原理

如果把互联网看作是各个站点相互引用、串联形成的一张网,那爬虫顾名思义就是在这张网上穿梭的蜘蛛(Spider)。一个页面作为互联网中的一个节点,很可能会包含有指向其他页面的链接,可以理解为节点之间的连线。爬虫通过遍历节点之间的连线,确定页面之间的网络结构,抓取所需要的信息。

在开始之前,我们应该清楚一些基本的概念:

  • WWW (World Wide Web, 万维网) 是一个由互相连接的超文本页面组成的系统

  • 每个页面有对应的 URL(Uniform Resource Locator, 网址) 所标记

  • 页面通过 HTTP (Hypertext Transfer Protocol, 超文本传输协议) 传输

  • 网页使用 HTML(HyperText Markup Language, 超文本标记语言) 表示其页面结构

那么具体而言,爬虫程序的运行过程是:

  1. 寻找包含所需信息的页面 URL

  2. 通过 HTTP 获取页面

  3. 从 HTML 中解析出信息

  4. 从中发现更多包含所需信息的 URL,跳转到步骤2

在实现层面上,爬虫程序运行之初,需要提供给它一个 URL 列表,引导爬虫从这些页面开始访问。当爬虫访问这些 URL 时,会识别出页面中的所需的 URL,并将这些 URL 加入到待访问的 URL 列表中。URL 列表中的地址会以一系列策略递归地被爬虫所访问,爬虫会记录这些地址所对应的页面以及一些页面信息。

现代爬虫的基本结构

PySpider 简介

PySpider 是一个基于 Python 开发的强大爬虫系统,它具有以下特点:

  • 用户使用 Python 编写脚本以控制爬虫的工作流程

  • 包含基于 WebUI 的可视化脚本编辑器、任务监视器、项目管理器及结果预览工具

  • 可以使用 MySQL、MongoDB、Redis、SQLite、ElasticSearch、PostgreSQL 等工具结合 SQLAlchemy 作为存储后端

  • 可以使用 RabbitMQ、Beanstalk、Redis 和 Kombu 作为消息队列

  • 支持任务优先级、任务重试、周期任务、根据页面寿命自动重爬等高级功能

  • 分布式架构,支持 js 解析,支持 Python2 与 Python 3

总结一下,利用 PySpider,可以方便地搭建出专业的爬虫框架。

实战操作

1. 配置华为云服务

作为一个专业稳定的爬虫服务,而不是简单批量下载页面的工具,我们往往需要搭建一个服务器,来让它自动地、定期地去工作,这时一个稳定可信赖的云服务就至关重要了,我们这里就以业界领先的华为云服务为例,搭建爬虫的基础运行环境。

我们首先需要在 https://console.huaweicloud.com/ecm/?locale=zh-cn#/ecs/createVm 申请一个台云服务器。

我的服务器配置为

服务器配置

这里我选择了个人更偏好的 CentOS 7.3 系统,下面就以 CentOS 7.3 系统为例,继续接下来的搭建。

2. 环境准备

在安装 PySpider 前,我们可以做一些环境准备,来提升服务的稳定性,这也是在搭建服务时的好习惯。

首先更新 yum,这步会比较漫长

yum update -y

安装 EPEL(Extra Packages for Enterprise Linux),用以安装下面需要的包

yum install epel-release

安装依赖库

yum install python-pip python-devel libxml2-devel python-lxml libxslt-devel openssl-devel -y

升级 pip

pip install --upgrade pip

至此,运行环境及必需的依赖已升级至最新版本。下面我们根据喜好进行一些可选的配置,首先安装 MariaDB 作为爬虫的后端数据库。

yum install mariadb-server mariadb -y

启动 MariaDB 服务

systemctl start mariadb

如果有需要,可以设置数据库 root 用户的密码(your_password 应替换为你的密码),当然也可以不设置:

mysqladmin -u root password "your_password"

这时可以使用如下命令来检查 MariaDB 是否配置成功(如果未设置密码,直接使用 mysql 即可):

mysql -u root -p

然后输入刚才设置的密码,如果没有问题,应该可以看到以 MariaDB [(none)]> 的提示。

此时输入 SHOW DATABASES; 语句,查看所有数据库,如果有类似下面的输出,则配置正常。

MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

输入 exit 退出,进入下一步。

接下来,安装 Redis,作为消息队列使用。

yum install redis -y

在启动 Redis 之前,需要做一些设置,让 Redis 作为一个服务运行。首先创建一份配置文件:

mkdir -p /etc/redis
cp /etc/redis.conf /etc/redis/redis.conf

修改 /etc/redis/redis.conf ,将其中的 daemonize 项修改为 yes

daemonize yes

配置文件路径作为参数,启动 Redis 服务:

redis-server /etc/redis/redis.conf

3. 部署PySpider

在安装 PySpider 之前,需要先安装 mysql-connector 及 redis 两个依赖,而最新的 mysql-connector 2.2 有 protobuf 的依赖,protobuf 笔者目前还没找到合适的安装方法,所以这里退而求其次,安装不依赖 protobuf 的 mysql-connector 2.1.6

pip install mysql-connector==2.1.6 redis

安装 PySpider

pip install pyspider

创建 PySpider 配置目录

mkdir /etc/pyspider

/etc/pyspider 目录下创建 pyspider.conf.json 文件,以下可作为参考:

{
  "taskdb": "mysql+taskdb://root:your_password@localhost:3306/taskdb",
  "projectdb": "mysql+projectdb://root:your_password@localhost:3306/projectdb",
  "resultdb": "mysql+resultdb://root:your_password@localhost:3306/resultdb",
  "message_queue": "redis://localhost:6379/db",
  "webui": {
    "username": "sunny",
    "password": "your_user_password",
    "need-auth": true
  }
}

其中 taskdb, projectdbresultdb 分别为任务、项目及结果的数据库连接地址,这里我们用一个 MariaDB 服务存储这三类数据,上面的 root 为我们的 MariaDB 用户名,后面 your_password 应替换为之前设置的数据库密码。 message_queue 后应填写消息队列服务的地址,这里我们是将 Redis 做为消息队列使用。 webui 项中的 usernamepassword 是用来配置访问 WebUI 时的用户名和密码,也可以不设置用户名和密码,只需将 need-auth 改成 false 即可。

接下来创建一个工作文件夹,并启动爬虫

mkdir ~/pyspider
cd ~/pyspider
pyspider -c /etc/pyspider/pyspider.conf.json

此时访问 http://你的服务器IP地址:5000,应该可以看到 PySpider 的 Dashboard。

如果访问失败,很可能是防火墙组织了发往5000端口的数据包,这时我们需要打开5000端口

iptables -A INPUT -p tcp --dport 5000 -j ACCEPT
iptables --flush

此时重新启动爬虫,就可以访问 Dashboard 了,我们也可以结合 nohup 让爬虫服务运行在后台:

nohup pyspider -c /etc/pyspider/pyspider.conf.json &

至此 PySpider 服务的部署就完成了。

4. 爬取华为开发者社区

在搭建好服务之后,我们的目标是建立一个华为开发者社区所有文章的数据库,也就是要保存社区中所有的博客文章以及相关的数据。既然要对这些文章下手,那第一件事就是需要找到一个合适的文章列表。一个理想的列表应该具有这些特征:

  • 尽可能多地包含指向文章页面的链接

  • 可以通过跳转到下一页获取到所有文章的 URL

  • 列表根据时间由新到旧排序,方便获取到最新的文章

很幸运,我们发现社区博客页面的首页就有这样一个我们所期待的列表

博客首页

https://portal.huaweicloud.com/blogs

接下来我们正式开始上手 PySpider。首先输入之前设置的用户名和密码进入 Dashboard,然后点击 Create 新建一个 Project,命名为 huawei_developer,初始 URL 填写我们刚刚找到的列表页面https://portal.huaweicloud.com/blogs,类型选择 Script

创建 Project

右侧是我们写爬虫代码的编辑区,在 PySpider 中,on_start是整个爬虫的入口

@every(minutes=24 * 60)
def on_start(self):
    self.crawl('https://portal.huaweicloud.com/blogs', callback=self.index_page)

self.crawl 会获取页面,并调用 callback 来分析响应,@every 装饰器表示 on_start 会每天运行一次确保不会漏掉新的文章。

点击绿色的 Run 按钮,切换到 follow 页面,下面会出现一个链接,就是我们这里首先要爬取的第一个页面,我们这里点击绿色三角按钮

爬取首页

在首页上,我们需要提取两种链接:一是文章的链接,比如https://portal.huaweicloud.com/blogs/b16fc680d01811e7b8317ca23e93a891;二是列表翻到下一页的链接。

我们可以看到,在爬取首页后,默认设置的爬虫在页面上找出了127条链接。而其中我们想要的页面链接实际上只存在于文章列表的区域,下面我们将使用类似于 CSS 选择器的工具来过滤出我们想要的元素。

CSS 选择器是 CSS 用来选择 HTML 中元素的工具,CSS 通过这种简单的语法指定特定的元素并应用一些样式。由于包含信息的元素往往具有不同的样式,所以这里使用 CSS 选择器来过滤元素非常合适。关于 CSS 选择器的更多信息可以参考:

https://www.w3schools.com/cssref/css_selectors.asp

这里我们可以通过 PyQuery 内建的 response.doc 对象使用 CSS 选择器。

PySpider 提供了一个叫做 css selector helper 的工具,利用它我们可以更方便地通过点击元素得到它对应的 css 选择器。切换到 web 页面并点击 enable css selector helper 就可以使用它。

css selector helper

当光标移到元素上时,对应元素会变成橙色高亮状态。点击元素,一条CSS 选择器信息会出现在页面顶部,你可以进一步编辑来定位需要的元素,然后把 CSS 选择器加在你的代码里。

我们点击一条带链接的文章标题,然后将选择器加在代码里:

@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
    for each in response.doc('a.common-blog-title').items():
        self.crawl(each.attr.href, callback=self.detail_page)

在提取到文章链接的同时,我们也要考虑翻页操作。这里可以用同样的思路得到指向下一页的链接。值得注意的是,最后一页的页面上没有对应的翻页控件,因此需要做一个额外的判断,在有翻页按钮的情况下才向后翻页。此外,我们解析文章列表页的函数是 index_page 本身,所以翻页的回调函数应设为 self.index_page,修改后的代码为:

@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
    for each in response.doc('a.common-blog-title').items():
        self.crawl(each.attr.href, callback=self.detail_page)
    next = response.doc('.ucd-pager-next > a')
    if next:
        self.crawl(next.attr.href, callback=self.index_page)

再次点击 run,然后进入 follow 页,选择一个文章链接,点击三角进入详情。

我们可以加一些键值来提取和保存更多的信息:

@config(priority=2)
def detail_page(self, response):
    return {
        "url": response.url,
        "title": response.doc('.cloud-blog-detail-title').text(),
        "author": response.doc('.sub-content-username').text(),
        "release_time": response.doc('.article-write-time').text()[4:],
        "view_time": response.doc('.common-blog-eye').next().text(),
        "comment_time": response.doc('.common-blog-bubbling').next().text(),
        "tags": [i.text() for i in response.doc('.blog-menu-footer > a').items()],
        "summary": response.doc('.cloud-blog-detail-summary-tag').text(),
        "content": response.doc('#blogContent').html()
    }

在原先只保存 urltitle 的基础上,我们把文章相关的作者、发布时间、浏览次数、评论数、标签、摘要和正文都从页面上提取出来,具体的获取细节和上面类似,这里就不展开了。点击 run 可以看到提取的效果。

预览提取的数据

从预览来看,结果还是很符合我们的预期的。完成代码编辑和测试后,别忘了点右上角的 save,然后回到 Dashboard,将项目对的 status 改成 DEBUG 或者 RUNNING,然后点击 Run,爬虫就开始每天按计划进行爬取并更新数据啦。

任务完成后点击 Results 可以看到爬虫保存的数据,可以导出并做后续的加工处理。由于我们使用了 MariaDB 保存结果,实际上后续的数据处理过程也可以直接连接数据库获取数据。

总结

至此,我们的 PySpider 爬虫实战入门项目就完成了。华为开发者社区是一个开放的平台,因此数据获取也并没有受到太多阻碍,然而在实际的运用中,会遇到很多具有反爬虫策略的网站。道高一尺,魔高一丈,我们用上 ip 代理、模拟登陆、验证码识别、无头浏览器等等技术手段和网站维护人员斗智斗勇,还是有办法突破他们设置的封锁的。

这篇博文只是一个系列的开篇,后续我会为大家总结应对反爬虫策略的一些方法,以及数据分析和处理的技巧,欢迎大家一起交流。

相关文章

  • 10分钟上手搭建爬虫服务

    本文由博主最初发布于华为开发者社区,原地址:https://portal.huaweicloud.com/blog...

  • python快速上手flask搭建api服务器

    python快速上手flask搭建api服务器   首先安装Flask pip install flask   新...

  • 云服务搭建爬虫

    参考https://blog.csdn.net/weixin_42477251/article/details/8...

  • 利用docker和docker-compose 数据库 构建简单

    一:简介和安装docker 对于较大型的爬虫需求可以利用服务器搭建docker 的python爬虫框架,这样可以充...

  • Python爬虫代理池

    爬虫代理IP池 在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的...

  • Python爬虫代理池

    爬虫代理IP池 在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的...

  • 使用树莓派搭建爬虫服务器

    为什么使用树莓派搭建自己的爬虫服务器? 树莓派使用Linux操作系统,完美支持爬虫框架Scrapy所需要的环境 爬...

  • 爬虫 | 继Helloworld程序 『scrapy &

    前言天黑之后就在图书馆玩一个爬虫,就是那个开源的爬虫 -- scrapy!早几天就搭建了一个Redis集群服务器,...

  • 快速构建Python爬虫IP代理池服务

    在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的都是对应网站有效...

  • Python爬虫代理池

    在公司做分布式深网爬虫,搭建了一套稳定的代理池服务,为上千个爬虫提供有效的代理,保证各个爬虫拿到的都是对应网站有效...

网友评论

    本文标题:10分钟上手搭建爬虫服务

    本文链接:https://www.haomeiwen.com/subject/kbdlgxtx.html