PySpider 框架基本使用(存入MYSQL)
发布日期:2021-05-07 22:37:05 浏览次数:12 分类:精选文章

本文共 8768 字,大约阅读时间需要 29 分钟。

文章目录

1 pyspider介绍

一个国人编写的强大的网络爬虫系统并带有强大的WebUI。采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器。

功能强大的WebUI,包含脚本编辑器,任务监视器,项目管理器和结果查看器。

Pyspider框架:

多线程处理、去重处理、错误重试、结果监控、PyQuery提取、代码简洁、WebUI管理、JavaScript渲染

2 pyspider启动服务,进入WebUI界面

使用之前,先降低 tornado 版本(pyspider和jupyter要求的tornado版本有冲突)

pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com tornado==4.5.3# 使用完在切换回去# pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com  tornado --upgrade

降低版本后,执行命令来启动服务器

pyspider或pyspider all

在这里插入图片描述

接下来

打开浏览器,在地址栏输入:http://localhost:5000/

即可打开pyspider的web UI界面

在这里插入图片描述

界面的解释

在这里插入图片描述

3 pyspider项目的创建

Project Name:任务的名字,可以任意填

Start URL(s):爬取任务开始的地址,这里我们填目标网址的url,也可以先不填
在这里插入图片描述
在这里插入图片描述

注意右侧,pyspider 已经帮我们生成了一段代码,代码如下所示:

在这里插入图片描述

4 应用例子1

from pyspider.libs.base_handler import *import pymongo# Handler 是 pyspider 爬虫的主类# 整个爬虫的功能只需要一个 Handler 即可完成class Handler(BaseHandler):    headers= {       'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',    'Accept-Encoding':'gzip, deflate, sdch',    'Accept-Language':'zh-CN,zh;q=0.8',    'Cache-Control':'max-age=0',    'Connection':'keep-alive',    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36'    }    	# 可以将本项目的所有爬取配置统一定义到这里	# Headers	# Cookies	crawl_config = {   	'headers' : headers,	#"user_agent": "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36",	#"timeout": 120,	#"connect_timeout": 60,	#"retries": 5,	"fetch_type": 'js',	#"auto_recrawl": True,	}        # //数据库配置,用的monggodb    client = pymongo.MongoClient(host='localhost',port=27017)    db = client['trip']	# 填写第一个url地址,起始的url,start url 是要爬取的链接    # 点击run 后会先调用这个函数    # @every(minutes=24 * 60) 通知 scheduler(框架的模块) 每天运行一次    @every(minutes=24 * 60)    def on_start(self):        # self.crawl:爬取的主方法,被on_start调用,即可新建一个爬取请求        # 发起请求,把 Response 发给 index_page 函数,index_page将会接受response        # validate_cert=False 解决证书报错        self.crawl('https://www.tripadvisor.cn/Attractions-g294211-Activities-c47-China.html', callback=self.index_page,validate_cert=False)            # 爬取索引页    # 带http的链接    # @config(age=10 * 24 * 60 * 60) 设置任务的有效期限,在这个期限内目标爬取的网页被认为不会进行修改    @config(age=10 * 24 * 60 * 60)    def index_page(self, response):                '''        Parameters        ----------        参数为 Response 对象        response : TYPE            DESCRIPTION.        Returns        -------        将爬取的结果进行解析        生成新的爬取请求        '''        # 在 pyspider 中,内置了 response.doc 的 PyQuery 对象,让你可以使用类似 jQuery 的语法操作 DOM 元素。        # 默认是 a[href"="http ”],也就是说该方法解析了页面的所有链接        # 将 response 中 div.listing_title > a 标签拿到,循环每一个 a 标签        for each in response.doc('div.listing_info > div.listing_title > a').items():            # 再次发起请求,取出每一个a标签的连接,将结果返回给detail_page函数            # validate_cert=False 解决证书报错            self.crawl(each.attr.href, callback=self.detail_page,validate_cert=False)                    # 下一页   		# next = response.doc('.paginatiaon.naw.next').attr.href   		# self.crawl(next , callback=self.index_page)              # 爬取详情页    # 通过点击左边的->获取页面信息细节(包括url和title)    # @config(priority=2) 设定任务优先级    @config(priority=2)    def detail_page(self, response):        url = response.url,        title = response.doc('title').text(),        name = response.doc('#HEADING').text(),        paiming = response.doc('span.header_rating > div > a > span').text(),        phonenum = response.doc('div.blEntry.phone > span:nth-child(2)').text(),        dizhi = response.doc('div.detail_section.address.xh-highlight').text(),        youwanshijian = response.doc('#taplc_attraction_detail_listing_0 > div.section.hours > div').text()                 # 最终将需要的数据作为一个 dict 对象返回,即为最终的抓取结果        return {                "url":url,             "title":title,             "name":name,             "paiming":paiming,             "phonenum":phonenum,             "dizhi":dizhi,             "youwanshijian":youwanshijian                   }            # 如果没有这个函数,抓取到的数据将默认存储到 resultdb 本地的数据库    # 结果存入数据库中    # 接受detail_page返回结果    def on_result(self,result):    # 注意这里的if result:这句判断很重要,不然的会会报错,提示result是未定义类型的。        if result:            self.save_to_mongo(result)                 # insert到mongo    def save_to_mongo(self,result):        if self.db['chinastrip'].insert(result):            print('save to mongo',result)

5 应用例子2:爬取新闻标题

启动 PySpider

打开浏览器,在地址栏输入:http://localhost:5000/


https://www.chinca.org/CICA/Memberdynamics/List?p=1

在这里插入图片描述

在这里插入图片描述

run

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


当 pyspider 连上 PhantomJS 代理后,你就能通过在 self.crawl 中添加 fetch_type=‘js’ 的参数,开启使用 PhantomJS 抓取。

在这里插入图片描述


在这里插入图片描述

save

再次运行

在这里插入图片描述

在这里插入图片描述

也可以配合原网页

在这里插入图片描述
最终选择到所有需要的
在这里插入图片描述
点击保存并运行

在这里插入图片描述

下面就是寻找翻页规律

https://www.chinca.org/CICA/Memberdynamics/List?p=1

https://www.chinca.org/CICA/Memberdynamics/List?p=2
https://www.chinca.org/CICA/Memberdynamics/List?p=3

作如下修改

def __init__(self):        # self.page = 1        self.totalpage = 5        self.base_url = 'https://www.chinca.org/CICA/Memberdynamics/List?p='                            @every(minutes=24 * 60)    def on_start(self):        for i in range(1,self.totalpage+1):            self.crawl(self.base_url+str(i), callback=self.index_page,fetch_type='js')                    '''            while self.page <= self.totalpage:               self.crawl(self.base_url+str(self.page), callback=self.index_page,fetch_type='js')            self.page += 1        '''

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

返回主页面

将程序设置为 运行状态

在这里插入图片描述

点击 run

后台在不断请求数据

在这里插入图片描述
在这里插入图片描述

5页内容

在这里插入图片描述
在这里插入图片描述

这个脚本里只是单纯的将结果打印在pyspider 的web ui中,并没有存到其它地方。

默认情况下,会把爬取到的结果存放到result.db这个sqilite数据库中,但是为了方便操作,我们将结果存放到mysql中。

6 Pyspider把抓取的结果存入mysql数据库

#!/usr/bin/env python# -*- encoding: utf-8 -*-# Created on 2021-02-01 10:26:51# Project: newimport pymysqlfrom pyspider.libs.base_handler import *class Handler(BaseHandler):    # 连接数据库    def __init__(self):        # self.page = 1        self.totalpage = 2        self.base_url = 'https://www.chinca.org/CICA/Memberdynamics/List?p='        self.db = pymysql.connect('localhost',                                   'root',                                   '*****',                                   '**',                                   charset='utf8')#连接数据库         # 获得Cursor对象        cursor = self.db.cursor()        cursor.execute("DROP TABLE IF EXISTS FUN_TEST")            # 创建表        sql = """CREATE TABLE FUN_TEST (            title CHAR(255),            url CHAR(255),            from_ CHAR(255),            date_ CHAR(255),            content CHAR(255),            Typesetting CHAR(255)            )"""         cursor.execute(sql)        self.db.close()            def save_in_mysql(self, title,url,from_,date_,content,Typesetting):        try:            self.db = pymysql.connect('localhost',                                   'root',                                   '*****',                                   '***',                                   charset='utf8')#连接数据库            cursor = self.db.cursor()            sql = 'INSERT INTO FUN_TEST(title,url,from_,date_,content,Typesetting) VALUES ("%s","%s","%s","%s","%s","%s")'% (title[0],url[0],from_[0],date_[0],content[0],Typesetting);            print(sql)            cursor.execute(sql)            self.db.commit()            print('插入成功')        except Exception as e:            # print(e)            self.db.rollback()                           # 表示每天执行一次        @every(minutes=24 * 60)    def on_start(self):        for i in range(1,self.totalpage+1):            self.crawl(self.base_url+str(i), callback=self.index_page,fetch_type='js')        # 表示数据10天后就过期了    @config(age=10 * 24 * 60 * 60)    def index_page(self, response):        for each in response.doc('.kerconrtbor .clearfix a').items():            self.crawl(each.attr.href, callback=self.detail_page)                @config(priority=3)    def detail_page(self, response):               title = response.doc('title').text(),        url= response.url,        from_ = response.doc('.releasetime > span:nth-child(1)').text(),        date_ = response.doc('div.industry-news > div:nth-child(4) > span').text(),        content = response.doc('.industry-news > p:nth-child(1)').text(),        Typesetting = response.doc('.releasetime > span:nth-child(2)').text()        self.save_in_mysql(title,url,from_,date_,content,Typesetting)        return {               "title": response.doc('title').text(),            "url": response.url,            "from_":response.doc('.releasetime > span:nth-child(1)').text(),            "date_": response.doc('#aspnetForm > div.ermainwih > div.ermain > div.ercon.clearfix > div.industry-news > div:nth-child(4) > span').text(),            "content": response.doc('#aspnetForm > div.ermainwih > div.ermain > div.ercon.clearfix > div.industry-news > p:nth-child(5)').text(),            "Typesetting": response.doc('.releasetime > span:nth-child(2)').text()        }

再次运行

在这里插入图片描述

结果

在这里插入图片描述

上一篇:MongoDB 安装及基本使用(增删改查)
下一篇:词云图生成器使用帮助

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年03月23日 07时26分52秒