使用deathbycaptcha服务处理Google recaptcha v2时如何控制scrapy中的请求流?

2024-02-02

你好:)我正在使用 python 使用 scrapy 网络爬行框架,抓取网站并使用 Deathbycaptcha 服务解决我在其页面上遇到的验证码。我的下载延迟设置为 30 秒,我只抓取几页来获取基本信息,这样我就不会过多地占用网站带宽或任何其他类型的信息。我将抓取视为在常规浏览器上发生的体验。

那么首先我们来谈谈这些问题。

ISSUE 1(在代码中) 我如何让 scrapy 基本上停止创建新请求,或者在解决验证码时过多地弄乱验证码?我尝试了很多不同的方法,但都无济于事,而且我对 scrapy 还很陌生,所以我不太熟悉编辑下载器中间件或 scrapy 引擎代码,但如果这是唯一的方法,那就这样吧但我希望有一个非常简单且有效的解决方案,让验证码完成它的工作,而新的请求根本不会中断它。

ISSUE 2(在代码中) 我如何修复这个计时器功能,我认为它与第一个问题有点相关。如果验证码超时而没有解决,那么它永远不会重置captchaIsRunning布尔值并不断不允许验证码再次开始尝试解决。计时器是我尝试解决第一个问题的方法之一,但是......我收到了一个错误。不确定这是否与从其中提取的事实有关threading and timeit在导入声明中,但我认为这没有什么大的区别。谁能指导我修复 Timer 语句的正确方向?

就像我说的,deathbycaptcha API 运行得很好,当它有机会的时候,但 scrapy 请求确实很干扰,我还没有找到这个问题的相关解决方案。再说一次,我还不是一个 scrapy 专家,所以有些事情已经远远超出了我的舒适区,需要推动,但不要太用力,否则我最终会破坏一切 xD 感谢您的帮助,非常感谢!抱歉问这个超长的问题。

不管怎样,该页面可以让你查找几个结果,大约 40-60 个页面后,它会重定向到包含 recaptcha v2 的验证码页面。 Deathbycaptcha 服务有一个用于解决 recaptcha v2 问题的 API,但不幸的是,他们的解决时间有时可能会超过几分钟,这非常令人失望,但它确实发生了。于是我很自然地调整了自己的心态DOWNLOAD_TIMEOUT设置为240秒,以便它有足够的时间来解决验证码,并在此之后继续抓取,以便它不再重定向。我的scrapy设置如下:

CONCURRENT_REQUESTS = 1
DEPTH_LIMIT = 1
DOWNLOAD_DELAY = 30
CONCURRENT_REQUESTS_PER_DOMAIN = 1
CONCURRENT_REQUESTS_PER_IP = 1
DOWNLOAD_TIMEOUT = 240
AUTOTHROTTLE_ENABLED = True
# The initial download delay
AUTOTHROTTLE_START_DELAY = 10
# The maximum download delay to be set in case of high latencies
AUTOTHROTTLE_MAX_DELAY = 60

然后显然是其余的,但我认为这些是我的问题中最重要的。我启用了一个扩展,然后中间件中有一些额外的东西,因为我还在这个文件中使用 docker 和 scrapy-splash。

SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}

MYEXT_ENABLED = False
MYEXT_ITEMCOUNT = 100

EXTENSIONS = {
   'scrapy.extensions.telnet.TelnetConsole': None,
   'scrapy.extensions.spideroclog.SpiderOpenCloseLogging':500,
}

所以我不认为这个东西对验证码或下载器中间件有很大影响......但这里是我的抓取工具中的一些代码:

Python:

import sys
import os
sys.path.append(r'F:\Documents\ScrapyDirectory\scrapername\scrapername\spiders')
import deathbycaptcha
import json
import scrapy
import requests
from datetime import datetime
import math
import urllib
import time
from scrapy_splash import SplashRequest
from threading import Timer
from timeit import Timer

class scrapername(scrapy.Spider):
    name = "scrapername"
    start_urls = []

    global scrapeUrlList
    global charCompStorage
    global captchaIsRunning

    r = requests.get('http://example.com/examplejsonfeed.php')

    myObject = json.loads(r.text)

    #print("Loading names...")
    for o in myObject['objects']:
        #a huge function for creating basically a lot of objects and appending links created from these objects to the scrapeUrlList function

    print(len(scrapeUrlList))
    for url in scrapeUrlList:
        start_urls.append(url[1])
        #add all those urls that just got created to the start_urls list


    link_collection = []

    def resetCaptchaInformation():
        global captchaIsRunning
        if captchaIsRunning:
            captchaIsRunning = False

    def afterCaptchaSubmit(self, response):
        global captchaIsRunning
        print("Captcha submitted: " + response.request.url)
        captchaIsRunning = False

    def parse(self, response):
        global captchaIsRunning
        self.logger.info("got response %s for %r" % (response.status, response.url))

        if "InternalCaptcha" in response.request.url:
        #checks for captcha in the url and if it's there it starts running the captcha solver API
            if not captchaIsRunning:
            #I have this statement here as a deterrent to prevent the captcha solver from starting again and again and 
            #again with every new request (which it does)  *ISSUE 1*
                if "captchasubmit" in response.request.url:
                    print("Found captcha submit in url")
                else:
                    print("Internal Captcha is activated")
                    captchaIsRunning = True
                    t = Timer(240.0, self.resetCaptchaInformation)
                    #so I have been having major issues here not sure why?
                    #*ISSUE 2*
                    t.start()

                    username = "username"
                    password = "password"

                    print("Set username and password")

                    Captcha_dict = {
                    'googlekey': '6LcMUhgUAAAAAPn2MfvqN9KYxj7KVut-oCG2oCoK',
                    'pageurl': response.request.url}

                    print("Created catpcha dict")

                    json_Captcha = json.dumps(Captcha_dict)

                    print("json.dumps on captcha dict:")
                    print(json_Captcha)

                    client = deathbycaptcha.SocketClient(username, password)

                    print("Set up client with deathbycaptcha socket client")

                    try:
                        print("Trying to solve captcha")
                        balance = client.get_balance()

                        print("Remaining Balance: " + str(balance))

                        # Put your CAPTCHA type and Json payload here:
                        captcha = client.decode(type=4,token_params=json_Captcha)

                        if captcha:
                            # The CAPTCHA was solved; captcha["captcha"] item holds its
                            # numeric ID, and captcha["text"] item its a text token".
                            print("CAPTCHA %s solved: %s" % (captcha["captcha"], captcha["text"]))

                            data = {
                                'g-recaptcha-response':captcha["text"],
                            }

                            try:
                                dest = response.xpath("/html/body/form/@action").extract_first()
                                print("Form URL: " + dest)
                                submitURL = "https://exampleaddress.com" + dest
                                yield scrapy.FormRequest(url=submitURL, formdata=data, callback=self.afterCaptchaSubmit, dont_filter = True)

                                print("Yielded form request")

                                if '':  # check if the CAPTCHA was incorrectly solved
                                    client.report(captcha["captcha"])
                            except TypeError:
                                sys.exit()
                    except deathbycaptcha.AccessDeniedException:
                        # Access to DBC API denied, check your credentials and/or balance
                        print("error: Access to DBC API denied, check your credentials and/or balance")
            else:
                pass
        else:
            print("no Captcha")
            #this will run if no captcha is on the page that the redirect landed on
            #and basically parses all the information on the page

非常抱歉所有这些代码,感谢您耐心阅读它。如果您对为什么有些东西在那里有任何疑问,请询问,以便我可以解释。所以验证码确实解决了。这不是问题。当抓取工具运行并且发生许多请求并且遇到 302 重定向时,它会收到 200 响应并抓取页面,检测验证码并开始解决它。然后scrapy发送另一个请求,该请求在验证码页面上获取302重定向、200响应,并检测验证码并尝试再次解决。它多次启动 API 并浪费了我的令牌。因此if not captchaIsRunning:声明是为了阻止这种情况发生。所以这是我现在在遇到验证码时输出的 scrapy 日志,请记住在此之前的一切都很好,运行我的所有解析日志。

杂乱的日志:

2018-07-19 14:10:35 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dThomas%2520Garrett%26citystatezip%3dLas%2520Vegas%2c%2520Nv> from <GET https://www.exampleaddress.com/results?name=Thomas%20Garrett&citystatezip=Las%20Vegas,%20Nv>
2018-07-19 14:10:49 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dThomas%2520Garrett%26citystatezip%3dLas%2520Vegas%2c%2520Nv> (referer: None)
2018-07-19 14:10:49 [scrapername] INFO: got response 200 for 'https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dThomas%2520Garrett%26citystatezip%3dLas%2520Vegas%2c%2520Nv'
Internal Captcha is activated
2018-07-19 14:10:49 [scrapy.core.scraper] ERROR: Spider error processing <GET https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dThomas%2520Garrett%26citystatezip%3dLas%2520Vegas%2c%2520Nv> (referer: None)
Traceback (most recent call last):
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy\utils\defer.py", line 102, in iter_errback
    yield next(it)
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy_splash\middleware.py", line 156, in process_spider_output
    for el in result:
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\offsite.py", line 29, in process_spider_output
    for x in result:
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\referer.py", line 339, in <genexpr>
    return (_set_referer(r) for r in result or ())
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\urllength.py", line 37, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "F:\Program Files (x86)\Anaconda3\lib\site-packages\scrapy\spidermiddlewares\depth.py", line 58, in <genexpr>
    return (r for r in result or () if _filter(r))
  File "F:\Documents\ScrapyDirectory\scraperName\scraperName\spiders\scraperName- Copy.py", line 232, in parse
    t = Timer(240.0, self.resetCaptchaInformation)
  File "F:\Program Files (x86)\Anaconda3\lib\timeit.py", line 130, in __init__
    raise ValueError("stmt is neither a string nor callable")
ValueError: stmt is neither a string nor callable
2018-07-19 14:10:53 [scrapy.extensions.logstats] INFO: Crawled 63 pages (at 2 pages/min), scraped 13 items (at 0 items/min)
2018-07-19 14:11:02 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dSamuel%2520Van%2520Cleave%26citystatezip%3dLas%2520Vegas%2c%2520Nv> from <GET https://www.exampleaddress.com/results?name=Samuel%20Van%20Cleave&citystatezip=Las%20Vegas,%20Nv>
2018-07-19 14:11:13 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dSamuel%2520Van%2520Cleave%26citystatezip%3dLas%2520Vegas%2c%2520Nv> (referer: None)
2018-07-19 14:11:13 [scrapername] INFO: got response 200 for 'https://www.exampleaddress.com/InternalCaptcha?returnUrl=%2fresults%3fname%3dSamuel%2520Van%2520Cleave%26citystatezip%3dLas%2520Vegas%2c%2520Nv'
#and then an endless supply of 302 redirects, and 200 response for their crawl
#nothing happens, because the Timer failed, the captcha never solved?
#I'm not sure what is going wrong with it, hence the issues I am having

我仍然需要几周的经验来解决您的问题,但我会尝试使用 RetryMiddleware:

可能在重试代码中添加 302 就足够了:

RETRY_HTTP_CODES
Default: [500, 502, 503, 504, 408]

https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#retry-http-codes https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#retry-http-codes

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用deathbycaptcha服务处理Google recaptcha v2时如何控制scrapy中的请求流? 的相关文章

  • 如何正确地将 MIDI 刻度转换为毫秒?

    我正在尝试将 MIDI 刻度 增量时间转换为毫秒 并且已经找到了一些有用的资源 MIDI Delta 时间刻度到秒 http www lastrayofhope co uk 2009 12 23 midi delta time ticks
  • 如何迭代按值排序的 Python 字典?

    我有一本字典 比如 a 6 b 1 c 2 我想迭代一下by value 不是通过键 换句话说 b 1 c 2 a 6 最直接的方法是什么 sorted dictionary items key lambda x x 1 对于那些讨厌 la
  • 在 Tensorflow tf.nn.nce_loss 中出现 TypeError:'Mul' Op 的输入 'y' 的类型为 float32,与参数 'x' 的 int32 类型不匹配

    我正在研究 Tensor Flow 中的 Bag of Words 实现 并得到了 类型错误 Mul Op 的输入 y 的类型为 float32 与参数 x 的 int32 类型不匹配 在 tf nn nce loss 中 我尝试查看 tf
  • Django 模型在模板中不可迭代

    我试图迭代模型以获取列表中的第一个图像 但它给了我错误 即模型不可迭代 以下是我的模型和模板的代码 我只需要获取与单个产品相关的列表中的第一个图像 模型 py class Product models Model title models
  • Pandas 中允许重复列

    我将一个大的 CSV 包含股票财务数据 文件分割成更小的块 CSV 文件的格式不同 像 Excel 数据透视表之类的东西 第一列的前几行包含一些标题 公司名称 ID 等在以下列中重复 因为一家公司有多个属性 而不是一家公司只有一栏 在前几行
  • 使用 Python pandas 计算调整后的成本基础(股票买入/卖出的投资组合分析)

    我正在尝试对我的交易进行投资组合分析 并尝试计算调整后的成本基础价格 我几乎尝试了一切 但似乎没有任何效果 我能够计算调整后的数量 但无法获得调整后的购买价格有人可以帮忙吗 这是示例交易日志原始数据 import pandas as pd
  • 在Python中调整图像大小

    我有一张尺寸为 288 352 的图像 我想将其大小调整为 160 240 我尝试了以下代码 im imread abc png img im resize 160 240 Image ANTIALIAS 但它给出了一个错误TypeErro
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • 使用 OLS 回归预测未来值(Python、StatsModels、Pandas)

    我目前正在尝试在 Python 中实现 MLR 但不确定如何将我找到的系数应用于未来值 import pandas as pd import statsmodels formula api as sm import statsmodels
  • 在flatpak项目中使用scrapy脚本

    我正在构建一个 flatpak 构建的项目 我有一个按钮 当单击它时我希望它运行 scrapy 脚本来抓取数据 窗口用户界面
  • 从 python 发起 SSH 隧道时出现问题

    目标是在卫星服务器和集中式注册数据库之间建立 n 个 ssh 隧道 我已经在我的服务器之间设置了公钥身份验证 因此它们只需直接登录而无需密码提示 怎么办 我试过帕拉米科 它看起来不错 但仅仅建立一个基本的隧道就变得相当复杂 尽管代码示例将受
  • 如何从Python中的字符串中提取变量名称和值

    我有一根绳子 data var1 id 12345 name John White python中有没有办法将var1提取为python变量 更具体地说 我对字典变量感兴趣 这样我就可以获得变量的值 id和name python 这是由提供
  • 如何设置 Celery 来调用自定义工作器初始化?

    我对 Celery 很陌生 我一直在尝试设置一个具有 2 个独立队列的项目 一个用于计算 另一个用于执行 到目前为止 一切都很好 我的问题是执行队列中的工作人员需要实例化一个具有唯一 object id 的类 每个工作人员一个 id 我想知
  • Seaborn Pairplot 图例不显示颜色

    我一直在学习如何在Python中使用seaborn和pairplot 这里的一切似乎都工作正常 但由于某种原因 图例不会显示相关的颜色 我无法找到解决方案 因此如果有人有任何建议 请告诉我 x sns pairplot stats2 hue
  • python Soap zeep模块获取结果

    我从 SOAP API 得到如下结果 client zeep Client wsdl self wsdl transport transport auth header lb E authenticate self login res cl
  • 使用yield 进行字典理解

    作为一个人为的例子 myset set a b c d mydict item yield join item s for item in myset and list mydict gives as cs bs ds a None b N
  • 迭代 my_dict.keys() 并修改字典中的值是否会使迭代器失效?

    我的例子是这样的 for my key in my dict keys my dict my key mutate 上述代码的行为是否已定义 假设my dict是一本字典并且mutate是一个改变其对象的方法 我担心的是 改变字典中的值可能
  • 当鼠标悬停在上面时,intellisense vscode 不显示参数或文档

    我正在尝试将整个工作流程从 Eclipse 和 Jupyter Notebook 迁移到 VS Code 我安装了 python 扩展 它应该带有 Intellisense 但它只是部分更糟糕 我在输入句点后收到建议 但当将鼠标悬停在其上方
  • Ubuntu 上的 Python 2.7

    我是 Python 新手 正在 Linux 机器 Ubuntu 10 10 上工作 它正在运行 python 2 6 但我想运行 2 7 因为它有我想使用的功能 有人敦促我不要安装 2 7 并将其设置为我的默认 python 我的问题是 如
  • 从 Twitter API 2.0 获取 user.fields 时出现问题

    我想从 Twitter API 2 0 端点加载推文 并尝试获取标准字段 作者 文本 和一些扩展字段 尤其是 用户 字段 端点和参数的定义工作没有错误 在生成的 json 中 我只找到标准字段 但没有找到所需的 user fields 用户

随机推荐

  • 如何为 std::pair 引用包装器的范围定义 C++ 概念?

    请参阅下面的代码 也在这里https www godbolt org z hvnvEv1ar https www godbolt org z hvnvEv1ar 如果我取消注释任一约束 代码将无法编译rng or pair 我觉得我错过了一
  • Eclipse:在 GWT 项目的版本控制中存储哪些文件

    我正在 Eclipse 中使用 Mercurial 进行 GWT 项目以进行版本控制 我应该在版本控制下存储哪些文件 或者 也许更简洁地说 我应该哪些文件not存储 因为它们要么是 GWT 的一部分 要么是构建过程的工件 我正在使用 Ecl
  • 使用 if(isset($_POST['submit'])) 在脚本打开时不显示回显不起作用

    我的方法有点问题if isset POST submit 代码 我想要的是一些回声和一个表格 当脚本打开时不会出现 但我确实希望它在单击表单的提交按钮时显示 问题是当我包括if isset POST submit 函数 当我单击提交按钮时
  • 如何将 microbit 与 BLE 连接并监听按钮按下事件?

    2021 年 11 月 28 日编辑 如果您需要使用蓝牙低功耗将 microbit 连接到计算机 并在单击按钮时执行操作 直接跳并跟随 ukBaz https stackoverflow com users 7721752 ukbaz的回答
  • .net 4.0 中 MemoryCache 与 ObjectCache 有何区别?

    NET框架4 0有什么区别MemoryCache vs ObjectCache 在哪里使用哪个对象 ObjectCache 是一个抽象类 它演示了如何构建一个符合编写 ObjectCache 的人希望您遵守的规则的缓存 您不能直接实例化 O
  • 如何在共享主机上设置 cakephp?

    这是我用 Cake 无法做到的一件事 我已经尝试了几次 但无法弄清楚 我在 hostgator 上 如果有人能指出他们如何设置它 高级安装 它会有所帮助 Edit 我已阅读文档并收到错误 我想我读得还不够好 Edit我刚刚找到这个帖子 ht
  • Graphics2D:我应该使用 int 版本还是 float 版本?

    一些Graphics2D方法 例如drawString 有将坐标作为的版本int or float 有什么理由选择其中之一 同样 我应该使用较新的Shape类 例如Rectangle2D 使用浮点坐标 或使用Rectangle 将坐标定义为
  • ffmpeg 中的去隔行

    我已按照教程进行操作here http dranger com ffmpeg 将视频文件加载到 C 程序中 但帧不是去隔行的 据我所知 ffmpeg 可执行文件支持 deinterlace 开关 我如何在代码中执行此操作 我应该阅读哪些库
  • 如何将按钮名称绑定到内容?

    我有一个按钮列表
  • XSLT 复制所有节点,并按分隔符分割

    我正在寻找一个执行以下操作的 xslt 以输入 xml 为例
  • 无法与任何提供的主机建立套接字

    我正在努力解决 android 中的文件传输问题 我正在使用 smack 4 1 连接到 openfire 服务器 我的问题是 当我使用 Spark 到 Spark 文件传输时 它工作正常 但是当我从Spark 到 Android 或 An
  • 如何在 django 自定义身份验证后端访问请求?

    我想用 django 的身份验证执行以下操作 记录错误的登录尝试 在 x 次错误登录尝试后暂时锁定帐户 记录成功登录 我认为自定义身份验证后端将是解决方案 我可以做我想做的大部分事情 但我想记录进行尝试的用户的 IP 和 REMOTE HO
  • Excel Yield 函数的.NET 实现

    Excel 的名为 分析工具库 的插件提供了 收益率 函数 用于计算定期支付利息的证券的收益率 函数运行良好并返回正确的数据 我的理解是基于迭代的函数 在我的代码中实现它并不容易 我的问题是有人知道 见过 C 最终是其他语言 的实现并可以分
  • 在 Groovy 中获取由字符分隔的子字符串

    考虑下面的字符串 String names Bharath Vinayak Harish Punith 我想以它仅包含的字符串形式获得输出Bharath 字符串直到第一次出现 运算符 任何人都可以告诉我 我们该怎么做 在一般情况下 我同意s
  • Python 列表理解代价高昂

    我试图找到列表理解的效率 但它看起来比普通函数操作更昂贵 有人可以解释一下吗 def squares values lst for x in range values lst append x x return lst def main t
  • 如何在没有 root 访问权限的情况下在本地安装 CPAN 模块(DynaLoader.pm 第 229 行错误)?

    不能与其他模块一起使用 但举个例子 我使用 CPAN 设置安装了 Text CSV XS makepl arg gt q PREFIX lib 当我尝试运行 test pl 脚本时 perl 测试 pl usr bin perl use l
  • 计算n的最佳方法选择k?

    评估 价值 最有效的方法是什么 n choose k 我认为的蛮力方法是找到n k n k 通过单独计算每个阶乘 更好的策略可能是根据这个使用DP递归公式 https i stack imgur com Kq3OH png nCk n 1
  • WHERE IN问题中的SQL占位符,插入字符串失败

    作为我工作的一部分 我需要编写 SQL 查询来连接到我们的 PI 数据库 要生成查询 我需要传递一个array标签 本质上是主键 但这些必须作为字符串插入 由于这将是一个模块化查询并用于多个标签 因此使用了占位符 该查询依赖于 WHERE
  • OpenGL - ARB 扩展

    我使用的是 MacBook Pro 13 英寸 2010 年中 并且使用 OpenGL 我注意到 库中缺少一些功能 我在互联网上找到了有关我的硬件的规格 上面写着 支持OpenGL 3 3 这很奇怪 所以我打印了我的 OpenGL 版本并这
  • 使用deathbycaptcha服务处理Google recaptcha v2时如何控制scrapy中的请求流?

    你好 我正在使用 python 使用 scrapy 网络爬行框架 抓取网站并使用 Deathbycaptcha 服务解决我在其页面上遇到的验证码 我的下载延迟设置为 30 秒 我只抓取几页来获取基本信息 这样我就不会过多地占用网站带宽或任何