requests 200 scrapy超时_selenium咋和scrapy一起用捏?

最近反爬越来越严重啦~有些网站有心跳函数,破js还不如直接上selenium搞数据~

但如果大部分其他网站还是用scrapy的管道处理数据的话,单纯用selenium,就代表又要把管道删删改改丢到selenium的脚本中....

太麻烦了我拒绝!

其实可以用scrapy的中间件包裹selenium中的网页源码,丢回scrapy程序中采集~

相当于只是把selenium当做中间件工具一样使用~

话不多说直接上代码~

先把用浏览器打开网页的jio本写好~

1.操纵浏览器的selenium_chrome.py

#! /usr/bin/env python3# coding=utf-8from selenium import webdriverimport requestsimport sysimport timesys.path.append("./")import randomfrom fake_useragent import UserAgentfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.ui import WebDriverWait       #WebDriverWait注意大小写from selenium.webdriver.common.by import Byclass Chrome_selenium(object):    '''开启无头浏览器'''    def __init__(self):        self.chrome_options = webdriver.ChromeOptions()        # 看情况是显示界面 or无头模式。本地调试时可以开启界面看一下~        # linux服务器上只能用无头模式        self.chrome_options.add_argument('--headless')        self.chrome_options.add_argument('--no-sandbox')        self.chrome_options.add_argument('--disable-gpu')        # #https证书        self.chrome_options.add_argument('--ignore-certificate-errors')        # self.chrome_options.debugger_address = "127.0.0.1:9222"        #test        self.chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])        # chrome_driver = "/usr/bin/google-chrome"        # #设置请求头        self.chrome_options.add_argument(UserAgent(verify_ssl=False).random)        # 不需要图片和js的话可以把下面的注释打开~        # prefs = {        #    'profile.default_content_setting_values': {        #        'images': 2,  # 屏蔽图片        #        'javascript': 2,  # 屏蔽js        #        'notifications': 2,  # 屏蔽消息推送        #    }        # }        # # 添加屏蔽chrome浏览器禁用图片的设置        # self.chrome_options.add_experimental_option("prefs", prefs)        #test        # self.chrome_options.debugger_address = "127.0.0.1:9210"        self.client = webdriver.Chrome(options=self.chrome_options)        # # # 隐性等待        # self.client.implicitly_wait(30)        # # timeout        # self.client.set_page_load_timeout(30)        #时间看加载情况~        # # 隐性等待        self.client.implicitly_wait(120)        # timeout        self.client.set_page_load_timeout(160)        # # 窗口最大化        self.client.maximize_window()            def get_one_page(self, one_html_url):        '''获取one page的源码'''        try:            self.client.get(one_html_url)            # self.client.execute_script("window.scrollTo(0, document.body.scrollHeight);")            # 需要滚动到底部 或者点击 滑动之类动作的话,就用if根据网址规则来进行操作            if "www.zzzzz.com" in one_html_url:                # 执行这段代码,会获取到当前窗口总高度                js = "return action=document.body.scrollHeight"                # 初始化现在滚动条所在高度为0                height = 0                # 当前窗口总高度                new_height = self.client.execute_script(js)                while height < new_height:                    # 将滚动条调整至页面底部                    for i in range(height, new_height, 100):                        self.client.execute_script('window.scrollTo(0, {})'.format(i))                        time.sleep(0.5)                    height = new_height                    time.sleep(2)                    new_height = self.client.execute_script(js)            elif 'www.xxxxxx.com' in one_html_url:                # 等指定的元素加载完毕后,再                if '/cat' in one_html_url:                    try:                        element = WebDriverWait(self.client, 10).until(EC.presence_of_element_located((By.XPATH, '//div[@data-pagination-start]')))                        # print(f'element:{element}')                    except Exception as message:                        print('元素定位报错%s' % message)                    finally:                        pass                elif 'xxxxx.desktop.json' not in one_html_url:                    #//h2[contains(text(),"Details")]                    try:                        element = WebDriverWait(self.client, 10).until(EC.presence_of_element_located((By.XPATH, '//div[contains(@class,"horizontalSlider")]')))                        # print(f'element:{element}')                    except Exception as message:                        print('元素定位报错%s' % message)                    finally:                        pass                    # 超时就直接返回源码        except Exception as e:            print('client error:{}'.format(e))            # self.client.refresh()            return self.client.page_source        current_page_html = self.client.page_source        return current_page_html       

2.scrapy工程中的middlewares.py

...# 导入操作浏览器的脚本from selenium_chrome import Chrome_selenium# 用HtmlResponse封装源码from scrapy.http import HtmlResponse......class Seleniummiddleware(object):    def __init__(self):        self.chrome_selenium = Chrome_selenium()        self.request_session = requests.Session()    def process_request(self, request, spider):        if 'www.zzzz.com' in request.url:            one_list_page_source = self.chrome_selenium.get_one_page(request.url)            # time.sleep(30)  # 等待加载,  可以用显示等待来优化.            # print(f'one_list_page_source:{one_list_page_source}')            # 参数url指当前浏览器访问的url, 在这里参数url也可以用request.url            # 参数body指要封装成符合HTTP协议的源数据, 后两个参数可有可无            return HtmlResponse(url=request.url, body=one_list_page_source, encoding='utf-8',                                request=request)

这样搞完后,在scrapy的爬虫代码文件中,就可以和普通的爬虫response一样使用xpath函数来取值了~

一定要记得在爬虫代码中开启selenium的中间件~

20fd10d99e16e6ba9a5772ee1661d08d.png

搞完收工~

b122d4db2afbf4107ed04e7ece91e0b6.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值