鲲鹏弹性云服务器运行网络爬虫(上)
零
系统:ubuntu 18.04
爬虫:pyspider
容器引擎:docker
服务器:鲲鹏弹性云KC1
记录全部过程
一 开放5000端口
【控制台】-【弹性云服务器ECS】-【安全组】-【配置规则】-【添加规则】


二 Python 环境
分别是 依赖库, python3, pip包管理
1
2
3
4
5
  | 
sudo apt-get install python3-dev build-essential libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev
sudo apt-get install python3
sudo apt-get install python3-pip
  | 
 


二 pyspider 安装
pyspider是一个爬虫架构的开源化实现。主要的功能需求是:
- 抓取、更新调度多站点的特定的页面
 
- 需要对页面进行结构化信息提取
 
- 灵活可扩展,稳定可监控
 
去重调度,队列,抓取,异常处理,监控等功能作为框架,提供给抓取脚本,并保证灵活性。最后加上web的编辑调试环境,以及web任务监控,即成为了这套框架。

在安装的过程中遇到了错误,期间总共遇到过 3 次异常,超时错误,退出异常等,按照步骤一步步来,会好起来的。
执行下列命令,再次安装 pyspider,耐心等待几分钟,查看版本
1
2
  | 
apt-get install libcurl4-openssl-dev
pip3 install pyspider
  | 
 

三 phantomjs 安装
PhantomJS 是一个基于 webkit 的 javascriptAPI。它使用 QtWebKit 作为它核心浏览器的功能,使用webkit来编译解释执行JavaScript代码。任何你可以在基于 webki t浏览器做的事情,它都能做到。PhantomJS 的用处可谓非常广泛,诸如网络监测、网页截屏、无需浏览器的Web 测试、页面访问自动化等。
1
2
3
  | 
wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2
tar -jxvf phantomjs.tar.bz2
ln -s /usr/local/phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/bin/phantomjs
  | 
 


环境已经配置完毕,运行一下试试
四 异常
最会,应该还会遇到一个生命中的 BUG,本文可以说涵盖了安装过程的大部分问题
主要错误信息是
1
2
3
4
  | 
  File "/usr/local/lib/python3.6/dist-packages/wsgidav/wsgidav_app.py", line 118, in _check_config
    raise ValueError("Invalid configuration:\n  - " + "\n  - ".join(errors))
ValueError: Invalid configuration:
  - Deprecated option 'domaincontroller': use 'http_authenticator.domain_controller' instead.
  | 
 

执行以下命令
1
2
3
  | 
pip3 install wsgidav==2.4.1
# 终于启动
pyspider all
  | 
 

五 在本地电脑输入   ip:5000

预告: 下一篇博文,正式开始网络爬虫,将以小白的视角来记录,并不会晦涩难懂
鲲鹏弹性云服务器运行网络爬虫(下)
零
系统:ubuntu 18.04
爬虫:pyspider
服务器:鲲鹏弹性云KC1
记录全部过程
一  设置登录账号和密码
创建 db.json 文件,用于设置登录账号和密码
不要在 data 文件夹内创建 db.json,data 是 pyspider 第一次启动时创建的文件,保存着数据信息,所以最好每次运行都在 data 的父目录或者指定 data 目录位置,以保证旧数据存在。


执行命令启动
1
  | 
pyspider --config db.json all
  | 
 
在本地电脑,打开浏览器,输入服务器的ip地址:5000,即弹出登录对话框,输入之前设置的用户名和密码

二 创建第一个爬虫
简单的操作,见图



创建之后,自动生成基础代码,15 行横线处是待爬取的首页链接,19 行是查找详情页,也就是首页面的所有跳转链接,最后的方框则是返回的结果
三 实战
爬取网页:http://quotes.toscrape.com/
信息:名言内容,作者,标签
查看网页信息,每一句名言都是一个div,class=quote, 这里关键字是 quote
1
2
3
4
5
6
7
8
9
  | 
 	@every(minutes=24 * 60)
    def on_start(self):
        self.crawl('http://quotes.toscrape.com/', callback=self.index_page)
    @config(age=10 * 24 * 60 * 60)
    def index_page(self, response):
        results = []
        for each in response.doc('.quote').items():
        	pass
  | 
 


F12 查看元素,元素选择器(图片中红标1)选择作者名,在右边代码栏可见该标签,其它标签属性有 itemprop="author" ,以此类推
代码可以这样写
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
  | 
 		# 名言结果集
 		results = []
 		# 循环每一句名言
        for each in response.doc('.quote').items():
            # 名言
            comment = each.find('[itemprop="text"]').text()
            # 作者
            author = each.find('[itemprop="author"]').text()
            # 标签
            tags = each.find('.tags .tag').items()
            # 标签结果集
            tagList = []
            for tag in tags:
                tagList.append(tag.text())
     		# 将查询到名言封装到名言结果集
            results.append({
                "comment": comment,
                "author": author,
                "tagList": tagList
            })
  | 
 

结果

四 将结果存储到 MongoDB
如何在鲲鹏弹性云部署 MongoDB,见下链
https://bbs.huaweicloud.com/forum/thread-28769-1-1.html
1
安装 pymongo
2
爬虫代码:
1
2
3
4
  | 
    # 连接 mongodb 数据库
    client = pymongo.MongoClient('119.3.248.122')
    # 库名为 demo1
    db = client['demo1']
  | 
 
1
2
3
4
5
6
7
8
9
  | 
    # 如果有结果集,调用存储数据库函数
    def on_result(self,result):
        if result:
            self.save_to_mongo(result)
    # 存到数据库
    def save_to_mongo(self,result):
        if self.db['comment'].insert(result):
            print('saved to mongo',result)
  | 
 

#化鲲为鹏,我有话说# 鲲鹏弹性云服务器运行网络爬虫(下)分页与总结
一 分页
通过之前的方法,用选择器点击图标,右侧代码框会自动定位该元素,这里可以看到通过 /page/2/ 以末尾的数字进行分页
获取该链接, 然后递归调用自己一直查询
1
2
  | 
next = response.doc('.next a').attr.href
self.crawl(next, callback=self.index_page)
  | 
 

二 源码
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  | 
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2019-11-24 03:27:43
# Project: demo1
from pyspider.libs.base_handler import *
import pymongo
class Handler(BaseHandler):
    crawl_config = {
         'itag': 'v224'
    }
     # 连接 mongodb 数据库
    client = pymongo.MongoClient('localhost')
    # 库名为 trip
    db = client['demo1']
    @every(minutes=24 * 60)
    def on_start(self):
        self.crawl('http://quotes.toscrape.com/', callback=self.index_page)
    @config(age=60)
    def index_page(self, response):
        self.crawl(response.url, callback=self.detail_page)
        next = response.doc('.next a').attr.href
        # 递归调用
        self.crawl(next, callback=self.index_page)
    @config(priority=2)
    def detail_page(self, response):
        results = []
        for each in response.doc('.quote').items():
            comment = each.find('[itemprop="text"]').text()
            author = each.find('[itemprop="author"]').text()# 作者
            # 标签
            tags = each.find('.tags .tag').items()
            # 标签结果集
            tagList = []
            for tag in tags:
                tagList.append(tag.text())
     		# 将查询到名言封装到名言结果集
            results.append({
                "comment": comment,
                "author": author,
                "tagList": tagList
            })
        return results
    # 保存
    def on_result(self,result):
        if result:
            self.save_to_mongo(result)
    # 存到数据库
    def save_to_mongo(self,result):
        if self.db['comment'].insert(result):
            print('saved to mongo',result)
  | 
 
三 常用方法
auto_recrawl 在任务过期后,自动重爬取
method 请求方法,默认 get 请求
params  追加参数 url, 感觉不常用
data   用于提交 post 请求的数据,可以用于登录?
connect_timeout   连接的超时时间,默认20秒
timeout  超时的请求时间,默认120秒
validate_cert   针对 https 网站,会爆证书错误,设置 false 可以忽略并继续访问,默认true
proxy  代理
etag  布尔类型变量,默认 true, 判断是否发生变化,没有发生变化就不爬了
fetch_type   请求的原始的 docment, 设置 =js 后,就可以调用 js 进行渲染
fetch_type='js'
js_script    可以执行js 操作, 比如滚动到网页的最下端,触发更多加载
1
  | 
window.scrollTo(0,document.body.scrollHeight);
  | 
 
js_run_at  将脚本加入到前面或者后面执行,默认是后面
js_viewport_width/js_viewport_height  视窗的大小
load_images  是否加载图片,默认 false
save 做多个函数之间传递变量,相当于  response 的session
taskid 唯一标识码,去重
四 web 浏览框
使用的时候发现这个浏览框非常的小,  改变方法见下图2
此方法只能用于本次, 一劳永逸需要修改配置文件
该路径是指向 pyspider 文件夹
sudo vim /usr/local/lib/python3.5/dist-packages/pyspider/webui/static/debug.min.css
增加 iframe 的样式:    height:900px  !important

