千家信息网

Scrapy爬虫框架集成selenium的方法

发表于:2025-02-14 作者:千家信息网编辑
千家信息网最后更新 2025年02月14日,这篇文章主要讲解了"Scrapy爬虫框架集成selenium的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Scrapy爬虫框架集成seleniu
千家信息网最后更新 2025年02月14日Scrapy爬虫框架集成selenium的方法

这篇文章主要讲解了"Scrapy爬虫框架集成selenium的方法",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Scrapy爬虫框架集成selenium的方法"吧!

    一、架构介绍

    Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方式从网站中提取所需的数据。但目前Scrapy的用途十分广泛,可用于如数据挖掘、监测和自动化测试等领域,也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。

    Scrapy 是基于twisted框架开发而来,twisted是一个流行的事件驱动的python网络框架。因此Scrapy使用了一种非阻塞(又名异步)的代码来实现并发。整体架构大致如下

    IO多路复用

    # 引擎(EGINE)(大总管)

    引擎负责控制系统所有组件之间的数据流,并在某些动作发生时触发事件。有关详细信息,请参见上面的数据流部分。

    # 调度器(SCHEDULER)

    用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL的优先级队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址

    # 下载器(DOWLOADER)

    用于下载网页内容, 并将网页内容返回给EGINE,下载器是建立在twisted这个高效的异步模型上的

    # 爬虫(SPIDERS)

    SPIDERS是开发人员自定义的类,用来解析responses,并且提取items,或者发送新的请求

    # 项目管道(ITEM PIPLINES)

    在items被提取后负责处理它们,主要包括清理、验证、持久化(比如存到数据库)等操作

    # 两个中间件

    -爬虫中间件

    -下载中间件(用的最多,加头,加代理,加cookie,集成selenium)

    二、安装创建和启动

    # 1 框架 不是 模块# 2 号称爬虫界的django(你会发现,跟django很多地方一样)# 3 安装        -mac,linux平台:pip3 install scrapy  -windows平台:pip3 install scrapy(大部分人可以)      - 如果失败:      1、pip3 install wheel #安装后,便支持通过wheel文件安装软件,wheel文件官网:https://www.lfd.uci.edu/~gohlke/pythonlibs      3、pip3 install lxml      4、pip3 install pyopenssl      5、下载并安装pywin32:https://sourceforge.net/projects/pywin32/files/pywin32/      6、下载twisted的wheel文件:http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted      7、执行pip3 install 下载目录\Twisted-17.9.0-cp36-cp36m-win_amd64.whl      8、pip3 install scrapy # 4 在script文件夹下会有scrapy.exe可执行文件        -创建scrapy项目:scrapy startproject 项目名   (django创建项目)      -创建爬虫:scrapy genspider 爬虫名 要爬取的网站地址   # 可以创建多个爬虫 # 5 命令启动爬虫                -scrapy crawl 爬虫名字              -scrapy crawl 爬虫名字 --nolog   # 没有日志输出启动 # 6 文件执行爬虫(推荐使用)        -在项目路径下创建一个main.py,右键执行即可      from scrapy.cmdline import execute    # execute(['scrapy','crawl','chouti','--nolog'])  # 没有设置日志级别    execute(['scrapy','crawl','chouti'])                      # 设置了日志级别

    三、配置文件目录介绍

    -crawl_chouti   # 项目名  -crawl_chouti # 跟项目一个名,文件夹    -spiders    # spiders:放着爬虫  genspider生成的爬虫,都放在这下面            -__init__.py      -chouti.py # 抽屉爬虫      -cnblogs.py # cnblogs 爬虫    -items.py     # 对比django中的models.py文件 ,写一个个的模型类    -middlewares.py  # 中间件(爬虫中间件,下载中间件),中间件写在这    -pipelines.py   # 写持久化的地方(持久化到文件,mysql,redis,mongodb)    -settings.py    # 配置文件  -scrapy.cfg       # 不用关注,上线相关的# 配置文件settings.pyROBOTSTXT_OBEY = False   # 是否遵循爬虫协议,强行运行USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'    # 请求头中的ua,去浏览器复制,或者用ua池拿LOG_LEVEL='ERROR' # 这样配置,程序错误信息才会打印,        #启动爬虫直接 scrapy crawl 爬虫名   就没有日志输出      # scrapy crawl 爬虫名 --nolog  # 配置了就不需要这样启动了# 爬虫文件class ChoutiSpider(scrapy.Spider):    name = 'chouti'   # 爬虫名字    allowed_domains = ['https://dig.chouti.com/']  # 允许爬取的域,想要多爬就注释掉    start_urls = ['https://dig.chouti.com/']   # 起始爬取的位置,爬虫一启动,会先向它发请求    def parse(self, response):  # 解析,请求回来,自动执行parser,在这个方法中做解析        print('---------------------------',response)

    四、爬取数据,并解析

    # 1 解析,可以使用bs4解析from bs4 import BeautifulSoupsoup=BeautifulSoup(response.text,'lxml')soup.find_all()  # bs4解析soup.select()  # css解析# 2 内置的解析器response.css  response.xpath# 内置解析   # 所有用css或者xpath选择出来的都放在列表中  # 取第一个:extract_first()  # 取出所有extract()# css选择器取文本和属性:    # .link-title::text  # 取文本,数据都在data中    # .link-title::attr(href)   # 取属性,数据都在data中# xpath选择器取文本和属性    # .//a[contains(@class,"link-title")/text()]    #.//a[contains(@class,"link-title")/@href]# 内置css选择期,取所有div_list = response.css('.link-con .link-item')for div in div_list:    content = div.css('.link-title').extract()    print(content)

    五、数据持久化

    # 方式一(不推荐)  -1 parser解析函数,return 列表,列表套字典    # 命令   (支持:('json', 'jsonlines', 'jl', 'csv', 'xml', 'marshal', 'pickle')    # 数据到aa.json文件中  -2 scrapy crawl chouti -o aa.json   # 代码:lis = []for div in div_list:    content = div.select('.link-title')[0].text    lis.append({'title':content})    return lis# 方式二 pipline的方式(管道)   -1 在items.py中创建模型类   -2 在爬虫中chouti.py,引入,把解析的数据放到item对象中(要用中括号)   -3 yield item对象   -4 配置文件配置管道       ITEM_PIPELINES = {        # 数字表示优先级(数字越小,优先级越大)       'crawl_chouti.pipelines.CrawlChoutiPipeline': 300,       'crawl_chouti.pipelines.CrawlChoutiRedisPipeline': 301,            }  -5 pipline.py中写持久化的类        spider_open  # 方法,一开始就打开文件        process_item # 方法,写入文件        spider_close # 方法,关闭文件

    保存到文件

    # choutiaa.py 爬虫文件import scrapyfrom chouti.items import ChoutiItem  # 导入模型类class ChoutiaaSpider(scrapy.Spider):    name = 'choutiaa'    # allowed_domains = ['https://dig.chouti.com/']   # 允许爬取的域    start_urls = ['https://dig.chouti.com//']   # 起始爬取位置    # 解析,请求回来,自动执行parse,在这个方法中解析    def parse(self, response):        print('----------------',response)        from bs4 import BeautifulSoup        soup = BeautifulSoup(response.text,'lxml')        div_list = soup.select('.link-con .link-item')        for div in div_list:            content = div.select('.link-title')[0].text            href = div.select('.link-title')[0].attrs['href']            item = ChoutiItem()  # 生成模型对象            item['content'] = content  # 添加值            item['href'] = href            yield item  # 必须用yield    # items.py 模型类文件import scrapyclass ChoutiItem(scrapy.Item):    content = scrapy.Field()    href = scrapy.Field()# pipelines.py 数据持久化文件class ChoutiPipeline(object):    def open_spider(self, spider):        # 一开始就打开文件        self.f = open('a.txt', 'w', encoding='utf-8')    def process_item(self, item, spider):        # print(item)        # 写入文件的操作        self.f.write(item['content'])        self.f.write(item['href'])        self.f.write('\n')        return item    def close_spider(self, spider):        # 写入完毕,最后关闭文件        self.f.close()# setting.pyITEM_PIPELINES = {    # 数字表示优先级,越小优先级越高   'chouti.pipelines.ChoutiPipeline': 300,   'chouti.pipelines.ChoutiRedisPipeline': 301,}

    保存到redis

    # settings.psITEM_PIPELINES = {    # 数字表示优先级,越小优先级越高   'chouti.pipelines.ChoutiPipeline': 300,   'chouti.pipelines.ChoutiRedisPipeline': 301,}# pipelines.py# 保存到redisfrom redis import Redisclass ChoutiRedisPipeline(object):    def open_spider(self, spider):        # 不写参数就用默认配置        self.conn = Redis(password='123')  # 一开始就拿到redis对象    def process_item(self, item, spider):        print(item)        import json        s = json.dumps({'content': item['content'], 'href': item['href']})        self.conn.hset('choudi_article', item['id'], s)        return item    def close_spider(self, spoder):        pass        # self.conn.close()# chouti.pyimport scrapyfrom chouti.items import ChoutiItem  # 导入模型类class ChoutiaaSpider(scrapy.Spider):    name = 'choutiaa'    # allowed_domains = ['https://dig.chouti.com/']   # 允许爬取的域    start_urls = ['https://dig.chouti.com//']   # 起始爬取位置    # 解析,请求回来,自动执行parse,在这个方法中解析    def parse(self, response):        print('----------------',response)        from bs4 import BeautifulSoup        soup = BeautifulSoup(response.text,'lxml')        div_list = soup.select('.link-con .link-item')        for div in div_list:            content = div.select('.link-title')[0].text            href = div.select('.link-title')[0].attrs['href']            id = div.attrs['data-id']            item = ChoutiItem()  # 生成模型对象            item['content'] = content  # 添加值            item['href'] = href            item['id'] = id            yield item  # 必须用yield

    保存到MongoDB

    #一.下载并安装mongodbpip install pymongo
    #二、在settings中打开PIPELINES并把数据库相应配置写入ITEM_PIPELINES = {    '.pipelines.ChoutiPipeline': 300,}MONGODB_HOST = '127.0.0.1'# 端口号,默认27017MONGODB_PORT = 27017# 设置数据库名称MONGODB_DBNAME = 'Chouti'# 存放本数据的表名称MONGODB_DOCNAME = 'Chouti'
    #三.修改pipelines文件import pymongofrom scrapy.utils.project import get_project_settingssettings = get_project_settings()class DouluodaluPipeline(object):    def __init__(self):        # 获取setting主机名、端口号和数据库名称        host = settings['MONGODB_HOST']        port = settings['MONGODB_PORT']        dbname = settings['MONGODB_DBNAME']        # 创建数据库连接        client = pymongo.MongoClient(host=host,port=port)        # 指向指定数据库        mdb = client[dbname]        # 获取数据库里面存放数据的表名        self.post = mdb[settings['MONGODB_DOCNAME']]    def process_item(self, item, spider):        data = dict(item)        # 向指定的表里添加数据        self.post.insert(data)        return item

    保存到mysql

    import pymysql.cursorsclass MySQLPipeline(object):    def __init__(self):        # 连接数据库        self.connect = pymysql.connect(            host='127.0.0.1',  # 数据库地址            port=3306,  # 数据库端口            db='scrapyMysql',  # 数据库名            user='root',  # 数据库用户名            passwd='root',  # 数据库密码            charset='utf8',  # 编码方式            use_unicode=True)        # 通过cursor执行增删查改        self.cursor = self.connect.cursor()    def process_item(self, item, spider):        self.cursor.execute(            """insert into mingyan(tag, cont)            value (%s, %s)""",  # 纯属python操作mysql知识,不熟悉请恶补            (item['tag'],  # item里面定义的字段和表字段对应             item['cont'],))        # 提交sql语句        self.connect.commit()        return item  # 必须实现返回

    六、动作链,控制滑动的验证码

    from selenium import webdriverfrom selenium.webdriver import ActionChainsimport timebro=webdriver.Chrome(executable_path='./chromedriver')bro.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')bro.implicitly_wait(10)#切换frame(很少)bro.switch_to.frame('iframeResult')div=bro.find_element_by_xpath('//*[@id="draggable"]')# 1 生成一个动作练对象action=ActionChains(bro)# 2 点击并夯住某个控件action.click_and_hold(div)# 3 移动(三种方式)# action.move_by_offset() # 通过坐标(x,y)# action.move_to_element() # 到另一个标签# action.move_to_element_with_offset() # 到另一个标签,再偏移一部分for i in range(5):    action.move_by_offset(10,10)# 4 真正的移动action.perform()# 5 释放控件(松开鼠标)action.release()async def login():    for res in setting.user:        try:            username = res[0]            password = res[1]            # headless参数设为False,则变成有头模式            browser = await launch(                {'headless': False}            )            # 打开一个页面            page = await browser.newPage()            await page.setViewport(viewport={'width': 1280, 'height': 800})            res = await page.goto('https://login.taobao.com/', options={'timeout': 10000})            await page.type('#fm-login-id', username)            await page.type('#fm-login-password', password)            await page.waitFor(1000)  # 等待时间            slider = await page.querySelector('#nc_1_n1z')  # 是否有滑块            if slider:                try:                    print('有滑块')                    await page.hover('#nc_1_n1z')  # 不同场景的验证码模块能名字不同。                    await page.mouse.down()                    await page.mouse.move(2000, 0, {'delay': random.randint(1000, 2000)})                    await page.mouse.up()                except Exception as e:                    print(e)                    input('验证失败,人工登录:')            else:                print('没有滑块')            await page.click("#login-form > div.fm-btn > button")  # 点击登录            input('进入登录成功页面后,按回车:')            return page        except Exception as e:            continue

    七、提高爬取效率

    - 在配置文件中进行相关的配置即可:(默认还有一套setting)#1 增加并发:默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。#2 提高日志级别:在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = 'INFO'# 3 禁止cookie:如果不是真的需要cookie,则在scrapy爬取数据时可以禁止cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False# 4禁止重试:对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False# 5 减少下载超时:如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s

    八、fake-useragent池

    # pip3 install fake-useragentfrom fake_useragent import UserAgentua = UserAgent(verify_ssl=False)print(ua.random)  # 随机获取一个UserAgent

    九、中间件配置

    #大中间件:下载中间件,爬虫中间件# 1 写在middlewares.py中(名字随便命名)# 2 配置生效()# 爬虫中间件SPIDER_MIDDLEWARES = {   'cnblogs_crawl.middlewares.CnblogsCrawlSpiderMiddleware': 543,}# 下载中间件DOWNLOADER_MIDDLEWARES = {   'cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware': 543,}# 下载中间件# 在cnblogs_crawl.middlewares.CnblogsCrawlDownloaderMiddleware中有五个方法# 请求出去的时候def process_request(self, request, spider)        # Must either:    # - return None:   # 返回none继续处理,进入下一个中间件    # - return Response: 当次请求结束,把Response丢给引擎处理(可以自己爬,包装成Response)    # - return Request : 相当于把Request重新给了引擎,引擎再去做调度    # - 抛异常:执行process_exception# 请求回来的时候def process_response(self, request, response, spider)        # - return a Response object :继续处理当次Response,继续走后续的中间件    # - return a Request object:重新给引擎做调度        # - 抛异常:执行process_exception# 请求异常的时候def process_exception(self, request, exception, spider)        # - return None: 不处理异常,继续丢给下面    # - return a Response:停止异常处理,不丢给下面。给引擎。Response给爬虫分析数据    # - return a Request:停止异常处理,不丢给下面。给引擎。Request重新调度

    process_exception 错误处理

    class CnblogsSpider(scrapy.Spider):    name = 'cnblogs4'    allowed_domains = ['www.cnblogs.com']    start_urls = ['http://wwwsadasd.cnblogs.com/']   # 错误的网址,报错走异常处理# 走异常处理,重新返回一个正确的Request对象def process_exception(self, request, exception, spider):    print(request.url)  # http://wwwsadasd.cnblogs.com/    from scrapy.http import Request    return Request('http://www.cnblogs.com/',callback=spider.parser_detail)

    process_request 加代理,加cookie等

        def process_request(self, request, spider):        # 1 加cookie(request.cookies就是访问该网站的cookie)        print(request.cookies)        request.cookies={'name':"jeff",'age':18}  # 从你的cookie池中取出来的,  字典        print(request.cookies)        # 2 加代理        request.meta['proxy']=self.get_proxy()   # 从代理池中获取一个        print(request.meta['proxy'])        # 3 修改ua        from fake_useragent import UserAgent   # ua模块,随机获取一个        ua = UserAgent(verify_ssl=False)        request.headers['User-Agent']=ua.random        print(request.headers)# 代理池def get_proxy(self):    import requests    ret=requests.get('http://0.0.0.0:5010/get').json()['proxy']    print(ret)    return ret        return None

    十、集成selenium

    #可在两个地方集成。#1.process_request(请求出去的时候)  # 推荐写这里,少请求一次。直接集成封装#2.process_response(请求回来的时候) # 不推荐,因为夺走了一次请求,回来再集成封装# 方案一:缺点很大。每次一请求都要打开一个bro浏览器def process_request(self, request, spider):    from selenium import webdriver    from scrapy.http import HtmlResponse    bro = webdriver.Chrome(executable_path='../chromedriver')    bro.get(request.url)    text = bro.page_source    response = HtmlResponse(url=request.url, body=text.encode('utf-8'), status=200)    return response# 方案二:改进为一开始就打开一个bro浏览器,后面都用这一个broclass CnblogsSpider(scrapy.Spider):    name = 'cnblogs'    from selenium import webdriver    # 在爬虫一开始就打开bro对象    bro = webdriver.Chrome(executable_path='../chromedriver')      # 在爬虫中新添加的方法:关闭bro    def close(spider, reason):            spider.bro.close()  # 爬虫结束关闭# 中间件中def process_request(self, request, spider):    from scrapy.http import HtmlResponse    spider.bro.get(request.url)  # 每个请求使用一个bro    text = spider.bro.page_source    response = HtmlResponse(url=request.url, body=text.encode('utf-8'), status=200)    return response

    十一、指纹和布隆过滤器实现增量爬取

    什么是增量爬取?

    -增量爬取(100链接,150个链接)

    • -已经爬过的,放到某个位置(mysql,redis中:集合)

    • -如果用默认的,爬过的地址,放在内存中,只要项目一重启,就没了,它也不知道我爬过那个了,所以要自己重写去重方案

    -你写的去重方案,占得内存空间更小

    -bitmap方案

    -BloomFilter布隆过滤器

    网址指纹

    # 一、网址指纹from scrapy.http import Requestfrom scrapy.utils.request import request_fingerprint# 这种网址是一个request1 = Request(url='https://www.baidu.com/s?name=jeff&age=18')request2 = Request(url='https://www.baidu.com/s?age=18&name=jeff')ret1=request_fingerprint(requests1)ret2=request_fingerprint(requests2)print(ret1) # 6961985868392ae44c15ada494ddeda856cf75fcprint(ret2) # 6961985868392ae44c15ada494ddeda856cf75fc

    布隆过滤器

    # 安装# 1.需要先安装bitarray  #下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/# 2.下载好之后 pip3 install 文件拖进去# 3.pip3 install pybloom_live#ScalableBloomFilter 可以自动扩容from pybloom_live import ScalableBloomFilterbloom = ScalableBloomFilter(initial_capacity=100, error_rate=0.001, mode=ScalableBloomFilter.LARGE_SET_GROWTH)url = "https://www.baidu.com/s?name=jeff&age=18"url2 = "https://www.baidu.com/s?age=18&name=jeff"bloom.add(url)print(url in bloom)print(url2 in bloom)

    使用一:添加网址(不推荐)

    #BloomFilter 是定长的from pybloom_live import BloomFilterbf = BloomFilter(capacity=1000)url='www.baidu.com'bf.add(url)print(url in bf)print("www.liuqingzheng.top" in bf)

    使用二:添加网址指纹(推荐),配合指纹使用

    from scrapy.http import Requestfrom scrapy.utils.request import request_fingerprintfrom pybloom_live import BloomFilterrequest1 = Request(url='https://www.baidu.com/s?name=jeff&age=18')request2 = Request(url='https://www.baidu.com/s?age=18&name=jeff')ret1=request_fingerprint(request1)ret2=request_fingerprint(request2)print(ret1) # 6961985868392ae44c15ada494ddeda856cf75fcprint(ret2) # 6961985868392ae44c15ada494ddeda856cf75fcbf = BloomFilter(capacity=1000) # 1000容量bf.add(ret2)if ret1 in bf:    print('已经爬过此网站,True')else:    bf.add(ret1)  # 添加    print('还没有爬过此网站,返回false')

    十二、分布式爬虫

    github地址:https://github.com/rmax/scrapy-redis# 1 安装pip3 install scrapy-redis# 源码部分,不到1000行,# 1 原来的爬虫继承from scrapy_redis.spiders import RedisSpiderclass CnblogsSpider(RedisSpider):      #start_urls = ['http://www.cnblogs.com/']    redis_key = 'myspider:start_urls'  # 起始地址为空,在redis中拿# 2 在setting中配置  SCHEDULER = "scrapy_redis.scheduler.Scheduler"  DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"  ITEM_PIPELINES = {      'chouti.pipelines.Pipeline': 300,               # 用自己的入库类,比如mysql中     # 'scrapy_redis.pipelines.RedisPipeline': 300  # 存在别人写好的redis入库类  }REDIS_PARAMS  = {'password':'123'}   # 如果redis有密码就配置#其他更多配置见github# 3 多台机器上启动scrapy# 4 向reids中发送起始urlredis-cli lpush myspider:start_urls https://www.cnblogs.com

    十三、爬虫框架全站爬取使用案例

    可以同时启动两个爬虫,爬不同的网站。但是建议爬不同的网站新建项目

    chouti.py 爬虫:

    import scrapyfrom chouti.items import ChoutiItem  # 导入模型类class ChoutiaaSpider(scrapy.Spider):    name = 'choutiaa'    # allowed_domains = ['https://dig.chouti.com/']   # 允许爬取的域    start_urls = ['https://dig.chouti.com//']   # 起始爬取位置    # 解析,请求回来,自动执行parse,在这个方法中解析    def parse(self, response):        print('----------------',response)        from bs4 import BeautifulSoup        soup = BeautifulSoup(response.text,'lxml')        div_list = soup.select('.link-con .link-item')        for div in div_list:            content = div.select('.link-title')[0].text            href = div.select('.link-title')[0].attrs['href']            id = div.attrs['data-id']            item = ChoutiItem()  # 生成模型对象            item['content'] = content  # 添加值            item['href'] = href            item['id'] = id            yield item  # 必须用yield

    cnblogs.py 爬虫:

    # -*- coding: utf-8 -*-import scrapyfrom bs4 import BeautifulSoupfrom chouti.items import CnblogsItem  # 导入模型类from scrapy.http import Requestclass CnblogsSpider(scrapy.Spider):    name = 'cnblogs'    start_urls = ['https://www.cnblogs.com/']    def parse(self, response):        print('------', response)        soup = BeautifulSoup(response.text, 'lxml')        div_list = soup.select('#post_list .post_item')        for div in div_list:            author = div.select('.post_item_foot a')[0].text            content_url = div.select('h4 a')[0].attrs['href']            title = div.select('h4')[0].text            content_summary = div.select('p')[0].text            item = CnblogsItem()            item['author'] = author            item['content_url'] = content_url            item['title'] = title            item['content_summary'] = content_summary            # print(f'''            # 作者:{author}            # 文章地址:{content_url}            # 标题:{title}            # 文章内容:{content_summary}            # ''')                        # 继续往深一层爬取,传递给content_parse            yield Request(content_url, callback=self.content_parse, meta={'item': item})        # 获取下一页的标签网址        next = soup.select('#paging_block > div > a:nth-last-child(1)')[0].attrs['href']        next = 'https://www.cnblogs.com/'+next        yield Request(next)   # 继续爬取下一页    def content_parse(self, response):        item = response.meta.get('item')        content = response.css('#cnblogs_post_body').extract_first()        if not content:            content = response.css('content').extract_first()        item['content'] = content        # print(item)        yield item

    items.py 模型类:

    # -*- coding: utf-8 -*-# Define here the models for your scraped items# See documentation in:# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass ChoutiItem(scrapy.Item):    content = scrapy.Field()    href = scrapy.Field()    id = scrapy.Field()class CnblogsItem(scrapy.Item):    author = scrapy.Field()    content_url = scrapy.Field()    title = scrapy.Field()    content_summary = scrapy.Field()    content = scrapy.Field()

    pipelines.py 数据持久化文件

    # -*- coding: utf-8 -*-# Define your item pipelines here# Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html# 保存到文件class Pipeline(object):    def open_spider(self, spider):        # choutiaa爬虫入库前        if spider.name == 'choutiaa':            # 一开始就打开文件            self.f = open('a.txt', 'w', encoding='utf-8')        # cnblog爬虫入库前        elif spider.name == 'cnblogs':            import pymysql            self.conn = pymysql.Connect(host='127.0.0.1', port=3306, db='cnblogs', user='root', password="123",autocommit=True)    def process_item(self, item, spider):        # choutiaa爬虫入库中        if spider.name == 'choutiaa':            # 写入文件的操作            self.f.write(item['content'])            self.f.write(item['href'])            self.f.write(item['id'])            self.f.write('\n')            return item        # cnblog爬虫入库中        elif spider.name == 'cnblogs':            print('cnblogs入库中')            curser = self.conn.cursor()            sql = 'insert into article (author,content_url,title,content_summary,content) values (%s,%s,%s,%s,%s)'            curser.execute(sql, (            item['author'], item['content_url'], item['title'], item['content_summary'], item['content']))    def close_spider(self, spider):        # choutiaa爬虫入库结束        if spider.name == 'choutiaa':            # 写入完毕,最后关闭文件            self.f.close()        # cnblog爬虫入库结束        elif spider.name == 'cnblogs':            print('cnblogs入库完毕')            self.conn.close()

    main.py

    from scrapy.cmdline import execute# execute(['scrapy','crawl','choutiaa'])execute(['scrapy','crawl','cnblogs'])

    感谢各位的阅读,以上就是"Scrapy爬虫框架集成selenium的方法"的内容了,经过本文的学习后,相信大家对Scrapy爬虫框架集成selenium的方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

    0