一个Scrapy项目实现同时爬取不同的网站,网站内不同的站点
发布日期:2021-05-10 06:29:58 浏览次数:5 分类:技术文章

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

Scrapy作为一个优秀的Python爬虫框架,深受博主喜爱,尽管博主从事大部分工作是前端开发,但也会对爬虫,数据库以及后台的工作感兴趣。

最近又有了新的任务,能够以相同的数据库表结构去存储爬取的数据;在以往,博主虽然说会爬虫,但也只是非常浅显的,一个Scrapy项目只能跑一个爬虫,而实际上是可以在一个Scrapy项目中写多个爬虫的。

前期准备工作

创建一个新的Scrapy项目,在工作间文件夹打开控制台,输入以下命令:

scrapy startproject xxx(xxx为项目名)

创建新项目

像上图,当你电脑已经成功安装scrapy之后,只需这一句命令就可以创建一个全新的scrapy项目了
目录结构如下:
初始化项目目录
这里博主修改了一下目录结构,因总共要爬取三个不同的网站,在spiders文件夹下添加了site01_spider.pysite02_spider.pysite03_spider.py三个爬虫文件,在demo目录下添加db.py数据库存储文件,在最外层大目录下添加demo_main.py启动爬虫文件,如下图:
修改目录结构

编写代码工作

db.py(新增):配置相关的SQL初始化创建表方法,数据库插件mysql使用pymysql插件,mssql则使用pymssql插件。

import pymssqlclass demoInfo(object):    def __init__(self, tableName):        self.tableName = tableName    def add(self, xxx):        # 这里做连接数据库,插入数据库操作        db = pymssql.connect(            host="xxx",            user="xxx",            password="xxx",            database="xxx"        )        cursor = db.cursor()        sql = "select * from 'xxxx'"        cursor.execute(sql)        db.commit()        cursor.close()        db.close()    def create(self, xxx):        # 这里做初始化创建表操作 SQL语句有变 基本同上        print('create')

items.py:配置需要爬取的字段。

class DemoItem(scrapy.Item):    # define the fields for your item here like:    name = scrapy.Field()    pass

middlewares.py:可编写用于随机选取USER_AGENTS的类方法,按需也可在下载中间件process_response回调里使用selenium做请求回调前的控制浏览器行为的操作(这里不做展开)。

pipelines.py:可根据爬虫名称来区分要插入的数据库。

from source.db import dbInfoclass DemoPipeline(object):    def process_item(self, item, spider):        dbName = ''        # 根据蜘蛛名来判断数据库的表名        if spider.name == 'site01_spider':            dbName = 'site01'        elif spider.name == 'site02_spider':            dbName = 'site02'        else:            dbName = 'site03'        source = dbInfo(dbName)        source.create(dbName)        source.add(item["name"])        return item

settings.py:项目配置文件,按需配置(这里也不做展开)。

source_main.py(新增):该文件作为爬虫启动的入口文件,可由用户输入决定所要启动的爬虫。

from scrapy.crawler import CrawlerProcessfrom scrapy.utils.project import get_project_settingsfrom demo.spiders.site01_spider import site01Spiderfrom demo.spiders.site02_spider import site02Spiderfrom demo.spiders.site03_spider import site03Spiderfrom demo.db import dbInfo# 在Scrapy框架内控制爬虫if __name__ == "__main__":    process = CrawlerProcess(get_project_settings())    	# 控制台主界面    main = int(input("请输入爬取网站:(1为site01 2为site02 3为site03)"))    if main == 1:        process.crawl("site01_spider")    elif main == 2:        process.crawl("site02_spider")    elif main == 3:        process.crawl("site03_spider")    else:        print("输入错误!")        pass    print('-----爬虫启动-----')    process.start()

site01到site03爬虫文件,这里举其中一个文件为例展开:

博主使用到了selenium,故需要Chromewebdriver支持,同时还需要相关的配置

import scrapyfrom demo.items import DemoItemfrom selenium import webdriverfrom selenium.webdriver.chrome.options import Options    # 使用无头浏览器# 无头浏览器设置chorme_options = Options()chorme_options.add_argument("--headless")chorme_options.add_argument("--disable-gpu")class site01Spider(scrapy.Spider):    name = 'site01_spider'    allowed_domains = [        'www.site01xx.com',        'www.site01yy.com',        'www.site01zz.com'    ]    start_urls = [        'https://www.site01xx.com/list/index.html'    ]    def __init__(self):        self.page = 1  # 当前页码        self.url_index = 0  # 当前url_list的下标值        # url_list可配置相同的网页结构,不同的站点的url,可支持不同的域名        # 如果为不同域名,需要在allowed_domains添加对应的允许域名        self.url_list = [            'https://www.site01xx.com/list/index.html',            'https://www.site01yy.com/list/index.html',            'https://www.site01zz.com/list/index.html'        ]        self.browser = webdriver.Chrome(chrome_options=chorme_options)        super().__init__()    # 整个爬虫结束后关闭浏览器    def close(self, spider):        print('退出爬虫')        self.browser.quit()    def parse(self, response):        # 每进入一次回调,page就自加1(页码)        self.page = self.page + 1        # 回调中对数据进行清洗,以及判断是否需要进行切页,进入详情页的操作        item = DemoItem()        name = 'xxx'        # 操作的最后,将数据压入字段后,传输给管道        item['name'] = name        yield item        # 假设总页码为100,爬完100页后进入下一个站点        if self.page <= 100:            yield scrapy.Request(url=self.url_list[self.url_index] + "?page=" + str(self.page), callback=self.parse)        else:            # 进入这里,证明已经爬完了某一个站点            print('-----进入下一个站点-----')            self.page = 1  # 页码重置为1            self.url_index = self.url_index + 1  # 数组下标自增1            yield scrapy.Request(url=self.url_list[self.url_index], callback=self.parse)

到这基本上就完成demo的编写,仅需按照自身需求替换相对应的示例代码即可完成。

总结

尽管爬虫并非博主的编程方向,但是博主还是非常乐意去钻研学习,多学习一些别的技术,对自身的提升还是非常有帮助的!

博主作为Python菜鸟级选手,文章有哪里写得不对的地方还请慷慨指出;同样的,有什么不懂的小伙伴也可以留言,博主当会尽力解答,大家一起共同进步!

参考网站:

转载地址:https://blog.csdn.net/weixin_43905402/article/details/107533358 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:使用squoosh网的压缩方法实现浏览器前端压缩图片功能
下一篇:饿了么UI组件库中,Image组件预览图片错位的解决

发表评论

最新留言

很好
[***.229.124.182]2023年12月11日 04时00分01秒