运维开发网

爬虫篇| pyspider 爬取链家网(八)

运维开发网 https://www.qedev.com 2021-03-06 12:39 出处:51CTO 作者:mb5ffd6eef9281a
pyspider框架介绍pyspider 是个强大的由python实现的爬虫系统。纯python的强大的webui,支持脚本编辑,任务监控,项目管理和pyspider 是个强大的由python实现的爬虫系统。结果查看消息队列支持,RabbitMQ,Beanstalk,Redis以及Kombu支持任务优先级,定时,失败重试等调度方案分布式架构,抓取js页面支持Python2和3pyspider框架安

爬虫篇| pyspider 爬取链家网(八)

pyspider框架介绍

pyspider 是个强大的由python实现的爬虫系统。

  • 纯python的

  • 强大的webui,支持脚本编辑,任务监控,项目管理和pyspider 是个强大的由python实现的爬虫系统。结果查看

  • 消息队列支持,RabbitMQ,Beanstalk,Redis以及Kombu

  • 支持任务优先级,定时,失败重试等调度方案

  • 分布式架构,抓取js页面

  • 支持Python2和3

pyspider框架安装

  • ubuntu

如果使用ubuntu,请先运行sudo apt update 再运行sudo apt upgrade 更新

apt-get install python python-dev python-distribute python-pip \

libcurl4-openssl-dev libxml2-dev libxslt1-dev python-lxml \

libssl-dev zlib1g-dev

删除wsgidav 然后重新安装2.4.1版本

  • windows

https://www.lfd.uci.edu/~gohlke/pythonlibs/ 中下载pycurl安装

windows 下安装成功,运行报如下错误:

 Deprecated option 'domaincontroller': use 'http_authenticator.domain_controller' instead.

解决方案:

删除wsgidav 然后重新安装2.4.1版本

pypsider入门

安装好pyspider后,创建一个项目文件夹用来存放相关文件,进入文件夹后运行pyspider命令,默认情况下会运行一个web服务端监听5000端口,通过http://localhost:5000即可访问pyspider的web管理界面,它看起来是这样的:

爬虫篇| pyspider 爬取链家网(八)

项目是独立的,但您可以将另一个项目作为模块导入 from projects import other_project

一期工程有5个状态:TODO,STOP,CHECKING,DEBUG和RUNNING

  • TODO - 创建一个脚本来编写

  • STOP- 您可以将项目标记为STOP您希望它停止(= =)。

  • CHECKING- 修改正在运行的项目时,为防止不完整修改,项目状态将CHECKING自动设置。

  • DEBUG/ RUNNING- 这两种状态对蜘蛛没有区别。但是将它标记为DEBUG第一次运行然后将其更改RUNNING为检查后是很好的。

  • 抓取速度被控制,rate并burst用令牌桶算法。

  • rate - 一秒钟内有多少请求

  • burst- 考虑到这种情况,rate/burst = 0.1/3这意味着蜘蛛每10秒抓一页。所有任务都已完成,项目每分钟检查最后更新的项目。假设找到3个新项目,pyspider将“爆发”并抓取3个任务而不等待3 * 10秒。但是,第四项任务需要等待10秒。

    要删除项目,请设置group为delete和状态STOP,等待24小时。

爬取目标(链家网)

因为我身处东莞,所以爬取的是东莞的

https://dg.lianjia.com/ershoufang/

爬虫篇| pyspider 爬取链家网(八)

  • 新建项目

爬虫篇| pyspider 爬取链家网(八)

进入到了开发界面

爬虫篇| pyspider 爬取链家网(八)

  • def on_start(selef)是脚本的入口。当你点击run按钮时,它会被调用。

  • self.crawl(url, callback=self.index_page)是最重要的接口。它会添加一个新的待爬取任务。大部分的设置可以通过self.crawl的参数去指定。

  • def index_page(self, response)接收一个response对象。response.doc是一个pyquery对象,它有一个类似jQuery选择器一样的接口,去解析页面元素。

  • def detail_page(self, response)返回一个字典结果。这个结果默认会被写入resultdb(结果数据库)。你可以通过复写on_result(self, result)方法来按照你自己的需求处理结果。

  • @every(minutes=24 * 60)这个装饰器会告诉调度器,on_start方法将会每天被调用。

  • @config(age=10 * 24 * 60 * 60)指定当self.crawl爬取的页面类型为index_page(当callback=self.index_page)时的age参数的默认值。参数age可以通过self.crawl(url, age=102460*60)crawl_config来指定,直接在方法参数中指定具有最高的优先级。

  • age=102460*60告诉调度器抛弃10天内爬取过的请求。默认情况下,相同URL不会被爬取两次,甚至你修改了代码。对于初学者来说,第一次运行项目然后修改它,在第二次运行项目的情况非常常见,但是它不会再次爬行(阅读itag了解解决方案)

  • @config(priority=2)标志着,detail page将会被优先爬取。

你可以通过点击绿色的run按钮,一步一步的调试你的脚本。切换到follows面板,点击play按钮前进。

注意点 :

  • 在使用self.crawl 函数时必须加上validate_cert=False 保证能够爬取https,不然会报599,SSL 错误解决办法

  • 想要爬取js生成的东西,需要使用PhantomJS,下载PhantomJS.exe丢掉·python.exe同路径下,通过添加参数fetch_type='js'来启用此功能self.crawl

由于链家网没有使用js生成数据,所以没有加上fetch_type='js',当我运行,得到了链家网首页 364条a标签的链接

爬虫篇| pyspider 爬取链家网(八)

获取需要url所在的xpath路径

爬虫篇| pyspider 爬取链家网(八)

在重新crawl方法,我们可以看出title和url的输出,说明没有问题

爬虫篇| pyspider 爬取链家网(八)

对于pyspider还有一个简介的方法就是通过css选择器来获取对应的css路径,从下面可以看出代码没有问题

爬虫篇| pyspider 爬取链家网(八)

  • 入库

对于入库需要写on_result方法和初始化方法具体如下

爬虫篇| pyspider 爬取链家网(八)

爬虫篇| pyspider 爬取链家网(八)

不到半分钟,数据爬取完毕

爬虫篇| pyspider 爬取链家网(八)

#!/usr/bin/env python

# -*- encoding: utf-8 -*-

# Created on 2019-07-21 17:08:14

# Project: lianjia

from pyspider.libs.base_handler import *

from lxml import etree

import pymysql

class Handler(BaseHandler):

    crawl_config = {

    }

    def __init__(self):

        db_config = {

            'host': '', #ip

            'user': '', #账号:不能用root的账号

            'password': '',

            'db': '', 

            'charset': 'utf8',

            'port': 3306 

        }

        self.db = pymysql.connect(**db_config) 

        self.cur = self.db.cursor()

        # 创建表items

        sql1 = 'create table if not exists items (url varchar(255) NOT NULL ,title VARCHAR(255) NOT NULL, price VARCHAR(255) NOT NULL, content mediumblob NOT NULL, Introduce mediumblob NOT NULL) '

        self.cur.execute(sql1)

        print('数据库创建成功')

    @every(minutes=24 * 60)

    def on_start(self):

        # 通过迭代来不断的访问新的链接

        for i in range(1,101):

            self.crawl('https://dg.lianjia.com/ershoufang/{}'.format(i), callback=self.index_page,validate_cert=False)

    @config(age=10 * 24 * 60 * 60)

    def index_page(self, response):

        xml = etree.HTML(response.text)

        urls = xml.xpath('//ul[@class="sellListContent"]//li/a/@href')

        # 获取每页的li中的url

        print(urls) #列表

        #for each in response.doc('a[href^="http"]').items():

            #self.crawl(each.attr.href, callback=self.detail_page,validate_cert=False)    

        for url in urls:

            self.crawl(url, callback=self.detail_page,validate_cert=False)

    @config(priority=2)

    def detail_page(self, response):

        # 爬取对应的title,url, pricecontent和Introduce

        return {

            "url": response.url,

            "title": response.doc('title').text(),

            "price": str(response.doc('.price > .total').text()) + '万',

            "content": response.doc('.base').text(),

            "Introduce":response.doc('.baseattribute > .content').text()

        }

    @config(priority=2)

    def on_result(self, result):

        sql = 'insert into items(url,title,price,content,Introduce) values(%s, %s,%s,%s,%s)'

        try:

            if result['url']:

                self.cur.execute(sql, (result['url'], result['title'],result['price'], result['content'],result['Introduce']))

        except Exception as e:

            self.db.rollback()

            print(e)

        else:

            self.db.commit()

不到半分钟爬取了1146条数据,但是有的数据的重复的,应该用集合来去重

爬虫篇| pyspider 爬取链家网(八)

■ Over ■

最后,祝有所学习,有所成长

回复【1024】获取学习资料

爬虫篇| pyspider 爬取链家网(八)

转发,好看支持一下,感谢

你的转发,就是对我最大的支持

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号