python 爬虫练手

鲲鹏弹性云服务器运行网络爬虫(上)

系统: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是一个爬虫架构的开源化实现。主要的功能需求是:

  1. 抓取、更新调度多站点的特定的页面
  2. 需要对页面进行结构化信息提取
  3. 灵活可扩展,稳定可监控

去重调度,队列,抓取,异常处理,监控等功能作为框架,提供给抓取脚本,并保证灵活性。最后加上web的编辑调试环境,以及web任务监控,即成为了这套框架。

1
pip3 install pyspider

在安装的过程中遇到了错误,期间总共遇到过 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

1
pip3 install pymongo

2

爬虫代码:

1
2
# 导入
import pymongo
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

Licensed under CC BY-NC-SA 4.0
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy