添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Scrapy爬虫框架,入门案例(非常详细)_scrapy crawl-CSDN博客

(1)、调度器(Scheduler):

抓取网页的网址的队列,由它来决定下一个要抓取的网址是什么,同时去除重复的网址。

(2)、下载器(Downloader): (相当于pyspider的fetcher)

下载器,是所有组件中负担最大的,它用于高速地下载网络上的资源。Scrapy的下载器代码不会太复杂,但效率高,主要的原因是Scrapy下载器是建立在twisted这个高效的异步模型上的(其实整个框架都在建立在这个模型上的)。

(3)、 爬虫(Spider): (相当于自己写的部分)

爬虫,是用户最关心的部份。用户定制自己的爬虫(通过定制正则表达式等语法),用于从特定的网页中提取自己需要的信息,即所谓的实体(Item)。 用户也可以从中提取出链接,让Scrapy继续抓取下一个页面。

(4)、 实体管道(Item Pipeline):

实体管道,用于处理爬虫(spider)提取的实体。主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。

(5)、Scrapy引擎(Scrapy Engine):

Scrapy引擎是整个框架的核心.它用来控制调试器、下载器、爬虫。实际上,引擎相当于计算机的CPU,它控制着整个流程。

主要文件结构

|-ProjectName              #项目文件夹
   |-ProjectName           #项目目录
      |-items.py           #定义(所要结果的)数据结构
      |-middlewares.py     #中间件
      |-pipelines.py       #数据处理
      |-settings.py        #全局配置
      |-spiders               
          |-__init__.py    #爬虫文件
          |-baidu.py
   |-scrapy.cfg            #项目基本配置文件

创建/运行

创建项目和创建自写文件(相当于pyspider自己编写的文件,但可以设置的地方更少)

scrapy startproject mySpider
scrapy genspider Spidername "website.com"

好像位置不对会有NotADirectoryError,不能像pyspider一样进入文件夹中source active然后scrapy startproject mySpider,先不看为什么了,可以这样:

python -m scrapy startproject projectName
cd projectName
python -m scrapy genspider Spidername "website.com"

将原本打印在窗口的所有信息保存在all.log的文件

python -m scrpay crawl spider_name  -s LOG_FILE=all.log

ctrl+c暂停后输入相同的命令即可继续(两次ctrl+c是强制退出)

可以在你当前所在位置创建项目

运行项目的命令
停止:ctrl+c一次不会马上停止Received SIGINT, shutting down gracefully. Send again to force,但一会就能停止,并且会有最后的log输出,两次会强制停止,但没有log,建议一次就行

python -m scrapy crawl Spidername

暂停/重启

Scrapy的暂停和重启及采坑记录 – 简书
scrapy的暂停与重启 – 简书

Scrapy的暂停和重启有两种方式: 官方文档介绍 中文文档

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

上述命令中:
somespider : 启动的爬虫名
crawls/somespider-1 :你创建的工作目录+爬虫序号

后面的somespider-1是用来区分不同的爬虫的,因为官方文档提到了:

要启用持久性支持,您只需通过JOBDIR设置定义作业目录。该目录将用于存储所有必需的数据以保持单个作业的状态(即蜘蛛运行)。重要的是要注意,此目录不能由不同的蜘蛛共享,甚至不能由同一个蜘蛛的不同作业/运行共享,因为它意味着用于存储单个作业的状态

交互式shell

Scrapy爬虫入门教程八 交互式 shell 方便调试 – 简书

scrapy shell <url>

shell也适用于本地文件。如果你想玩一个网页的本地副本,这可以很方便。shell了解本地文件的以下语法

# UNIX-style
scrapy shell ./path/to/file.html
scrapy shell ../other/path/to/file.html
scrapy shell /absolute/path/to/file.html
# File URI
scrapy shell file:///absolute/path/to/file.html

修改/配置/定制

全局配置:settings.py

类似pyspider中外面设置的rate/burst和里面设置的crawl_config

机器人协议

默认遵守,通常需要修改为False

USER_AGENT:默认是注释的
COOKIES_ENABLED:是否保存COOKIES,默认关闭,开机可以记录爬取过程中的COKIE,
DEFAULT_REQUEST_HEADERS:默认请求头

类似设置pyspider中的rate/burst

Scrapy 设置中 CONCURRENT_REQUESTS 及 DOWNLOAD_DELAY 等几个相关参数的作用 – bjjdkp的博客

主要CONCURRENT_REQUESTS 、 DOWNLOAD_DELAY
但是还有CONCURRENT_REQUESTS_PER_DOMAIN 、CONCURRENT_REQUESTS_PER_IP ,他们也有默认16,所以似乎要改CONCURRENT_REQUESTS也要改了这俩

在命令行中打印的log设置如

LOG_LEVEL=“WARNING”
RETRY_ENABLED = True  #打开重试开关
RETRY_TIMES = 3  #重试次数
DOWNLOAD_TIMEOUT = 3  #超时
RETRY_HTTP_CODES = [429,404,403,301,302]  #哪些状态码重试
REDIRECT_ENABLED = False #禁止重定向

似乎应该把超时时间不设置那么多,把重试次数设置多点保证没有url没有爬取
似乎应该设多点,不然总是重试次数很多很多,看着难受

TWISTED_REACTOR

避免下面的filedescriptor out of range in select()问题

TWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'

激活中间件

DOWNLOADER_MIDDLEWARES = {
  'AdvanceSpider.middlewares.ProxyMiddleware': 543,

字典的Key就是用点分隔的中间件路径,后面的数字表示这种中间件的优先级。由于中间件是按顺序运行的,因此如果遇到后一个中间件依赖前一个中间件的情况,中间件的顺序就至关重要。

激活项目管道组件

ITEM_PIPELINES = {
    'myproject.pipelines.PricePipeline': 300,
    'myproject.pipelines.JsonWriterPipeline': 800,

将项目管道组件的类加入ITEM_PIPELINES设置中以激活

中间件:middlewares.py

类似pyspider的self.crawl的参数,但是能够更加细致地视情况而定。
中间件可以在爬虫的请求发起之前或者请求返回之后对数据进行定制化修改:更换代理IP,更换Cookies,更换User-Agent,自动重试…
彻底搞懂Scrapy的中间件(一) – 青南 – 博客园
彻底搞懂Scrapy的中间件(二) – 青南 – 博客园
彻底搞懂Scrapy的中间件(三) – 青南 – 博客园

管道:pipelines.py 

Scrapy爬虫入门教程九 Item Pipeline(项目管道) – 简书

在保存结果前对爬虫爬取内容的进一步验证处理

在items被蜘蛛抓取后,它被发送到项目管道,它通过顺序执行的几个组件来处理它。

每个项目管道组件(有时称为“Item Pipeline”)是一个实现简单方法的Python类。他们接收一个items并对其执行操作,还决定该项目是否应该继续通过流水线或被丢弃并且不再被处理。

项目管道的典型用途是:

  • 清理HTML数据
  • 验证抓取的数据(检查项目是否包含特定字段)
  • 检查重复(并删除)
  • 将刮取的项目存储在数据库中
    同时还可以有不同的管道
    不同的pipeline可以处理不同爬虫的数据,通过spider.name属性来区分
    不同的pipeline能够对一个或多个爬虫进行不同的数据处理的操作,比如一个进行数据清洗,一个进行数据的保存
    同一个管道类也可以处理不同爬虫的数据,通过spider.name属性来区分

    定义结果的数据结构 :item.py

    定义想要的结果的数据结构,一般只是 description = scrapy.Field()
    Field方法实际上的做法是创建一个字典,给字典添加一个建,暂时不赋值,等待提取数据后再赋值。下面item的结构可以表示为:{‘name’:”,’descripition’:”}。

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

    生成请求 解析网页 :spider.py

    类似pyspider创建项目后编写的文件
    Spider — Scrapy 2.5.0 文档
    请求和响应 — Scrapy 文档
    选择器 — Scrapy 2.5.0 文档

    类属性设置

    默认生成的三个

    请求 start_requests()

    虽然scrapy genspider Spidername "website.com"创建的Spidername.py只有光秃秃的parse,默认使用其他文件中设置好的来对start_urls中的url进行请求,但实际上是可以在spider.py这个主要编写的文件来实现简单地设置代理、headers等、控制请求。类似pyspider的on_start(),是程序的入口。

    请求设置和传参

    类似pyspider中的self.crawl()

    请求头可以直接在参数中设置,也有callback可以设置回调函数(默认parse()),还有一个重要的参数dont_filter,设置遇到相同的url是否请求,默认不请求,通常需要设置dont_filter = True。

    meta中的特殊键会被scarpy识别,比如proxy,传参就可以使用其他键request.meta[‘save’] = data(不同于pyspider的self.crawl(‘save’ = data,’proxy’ = proxy))

    忽略SSL验证

    回调解析 parse(response)

    类似pyspider的index_page() detail_page(),可以再增加parse_sec(),并在对应的请求中设置callback

    类似pyspider中的response.etree.xpath,这里直接response.xpath,但这两者有些不同,前者是直接对网页内容进行xpath定位,但后者是selector的一个方法。所以会导致response.xpath(‘../text()’)并不返回定位节点文本的list,而是selector对象的一个list

    [<Selector xpath='//*[@id="ContentPlaceHolder1_divTimeStamp"]//div[@class="col-md-9"]/text()' data='\r\n                                    '>, <Selector xpath='//*[@id="ContentPlaceHolder1_divTimeStamp"]//div[@class="col-md-9"]/text()' data='66 days 19 hrs ago (Aug-17-2023 09:43...'>]

    需要在后面加上.getall()才能像pyspider一样得到文本列表

    提取写入items

    引入items里的类,并在parse函数中实例化,然后将提取的内容写入items并返回

    from ..items import ProjectiesItem
    items = ProjectiesItem()
    items['..'] = response.xpath...
    yield items

    项目加载器 Item Loaders

    工具类:ItemLoader,在parse()方法更变代码。
    小白学习Scrapy——Item Loaders(项目加载器) – 知乎
    Items只负责填充Item,而具体是怎么填充的,使用哪种机制或者手段去填充的,是由Item加载器负责的。Items负责数据装载的容器,而Item Loaders负责装载容器的机制或者是规则。

    项目加载器的设计目的是提供一种灵活、高效和简单的机制,通过蜘蛛或源格式(HTML、XML等)扩展和重写不同的字段解析规则,而不会成为维护的噩梦。
    要使用项目加载器,必须先实例化。可以使用类似dict的对象实例化它,也可以不使用,在这种情况下,项目将在Item Loader构造函数中使用属性中指定的Item类,自动ItemLoader.default_item_class 实例化。

    可以向同一项目字段添加多个值; 项目加载器将知道如何使用适当的处理函数“加入”这些值。

    from scrapy.loader import ItemLoader class BasicSpider(scrapy.Spider): name = 'basic' allowed_domains = ['web'] start_urls = ['https://game.bilibili.com/?spm_id_from=333.851.b_696e7465726e6174696f6e616c486561646572.3'] def parse(self, response): l =ItemLoader(item=ProjectiesItem(),response=response) l.add_xpath('new_game','//*[@id="track_new_game_booking"]/dl/dd/a/text()') l.add_xpath('hot_game','//*[@id="track_hot_game"]/dl/dd/a/text()') return l.load_item()
  • 处理器 MapCompose

    【scrapy】【四】scrapy项目_更改scrapy创建位置-CSDN博客
    用来处理爬取出来的内容格式,去掉空格…在xpath那里加上一些操作

    from scrapy.loader.processors import MapCompose,Join class BasicSpider(scrapy.Spider): name = 'basic' allowed_domains = ['web'] start_urls = ['https://game.bilibili.com/?spm_id_from=333.851.b_696e7465726e6174696f6e616c486561646572.3'] def parse(self, response): l =ItemLoader(item=ProjectiesItem(),response=response) l.add_xpath('new_game','//*[@id="track_new_game_booking"]/dl/dd/a/text()',MapCompose(unicode.strip)) l.add_xpath('hot_game','//*[@id="track_hot_game"]/dl/dd/a/text()') return l.load_item()

    链接提取器 Link Extractors

    类似pyspider的index_page的用处
    Scrapy-Link Extractors(链接提取器)-CSDN博客

    链接提取器 的 目的 就是从 网页(scrapy.http.Response 对象) 中,将最终 跟随(follow) 网页(即 scrapy.http.Response 对象) 的 链接 提取出来。简单的说:就是用于从服务器返回的 response 里抽取 url,用以进行之后的操作。

    可以在 Scrapy 中 直接使用 scrapy.linkextractors import LinkExtractor  提取链接,你也可以创建自己的自定义链接提取器,以满足您的需求通​​过实现一个简单的界面。

    执行爬虫文件时添加-o选项即可保存文件items.csv(在项目大文件夹中)(格式可以保存成json、jl、csv、xml等)

    scrapy crawl projectName -o items.csv

    对于json文件,在setting.js文件里添加,设置编码格式,否则会乱码:

    FEED_EXPORT_ENCODING='utf-8'

    失败url保存

    还是直接处理结果找出来吧

    直接设置代理/中间件设置代理

    测试了直接设置代理,成功,每次ip不一样

    class IptestSpider(scrapy.Spider):
        name = 'ipTest'
        allowed_domains = ['httpbin.org']
        start_urls = ['http://httpbin.org/ip']
        def start_requests(self):  
            proxy_address = ('aaa.com', '15818')
            username = "t19798354131"
            password = "p5vsp3"
            proxy = "http://%(user)s:%(pwd)s@%(proxy)s/" % {"user": username, "pwd": password, "proxy": ':'.join(proxy_address)}
            for i in range(50):
                yield scrapy.Request(self.start_urls[0], meta={"proxy": proxy},dont_filter = True)
        def parse(self, response):
            print(response.text)

    但是照着代理平台提供的代码示例,通过中间件设置代理就不行,压根没代理上,不清楚为什么

    好好好,才发现,而且换了一个代理还是这样,该不会真不能用隧道代理

    不过看了下好像也没几个403,但是重定向似乎也是ip问题

    1000个url结果:

    {'downloader/exception_count': 431,
     'downloader/exception_type_count/scrapy.core.downloader.handlers.http11.TunnelError': 1,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 1,
     'downloader/exception_type_count/twisted.web._newclient.ResponseFailed': 10,
     'downloader/exception_type_count/twisted.web._newclient.ResponseNeverReceived': 419,
     'downloader/request_bytes': 1318569,
     'downloader/request_count': 1409,
     'downloader/request_method_count/GET': 1409,
     'downloader/response_bytes': 19635917,
     'downloader/response_count': 978,
     'downloader/response_status_count/200': 974,
     'downloader/response_status_count/403': 4,
     'elapsed_time_seconds': 866.928672,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 24, 12, 12, 13, 279311),
     'httpcompression/response_bytes': 134794037,
     'httpcompression/response_count': 978,
     'httperror/response_ignored_count': 4,
     'httperror/response_ignored_status_count/403': 4,
     'item_scraped_count': 974,
     'log_count/DEBUG': 2370,
     'log_count/ERROR': 44,
     'log_count/INFO': 29,
     'log_count/WARNING': 10,
     'memusage/max': 518520832,
     'memusage/startup': 518520832,
     'response_received_count': 978,
     'retry/count': 409,
     'retry/max_reached': 22,
     'retry/reason_count/scrapy.core.downloader.handlers.http11.TunnelError': 1,
     'retry/reason_count/twisted.internet.error.TimeoutError': 1,
     'retry/reason_count/twisted.web._newclient.ResponseFailed': 10,
     'retry/reason_count/twisted.web._newclient.ResponseNeverReceived': 397,
     'scheduler/dequeued': 1409,
     'scheduler/dequeued/memory': 1409,
     'scheduler/enqueued': 1409,
     'scheduler/enqueued/memory': 1409,
     'start_time': datetime.datetime(2023, 10, 24, 11, 57, 46, 350639)}
    {'downloader/exception_count': 1670,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 1247,
     'downloader/exception_type_count/twisted.web._newclient.ResponseNeverReceived': 423,
     'downloader/request_bytes': 2429126,
     'downloader/request_count': 2598,
     'downloader/request_method_count/GET': 2598,
     'downloader/response_bytes': 18480744,
     'downloader/response_count': 928,
     'downloader/response_status_count/200': 928,
     'elapsed_time_seconds': 767.674732,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 24, 13, 23, 0, 103933),
     'httpcompression/response_bytes': 128308797,
     'httpcompression/response_count': 928,
     'item_scraped_count': 928,
     'log_count/DEBUG': 3463,
     'log_count/ERROR': 144,
     'log_count/INFO': 23,
     'memusage/max': 518586368,
     'memusage/startup': 518586368,
     'response_received_count': 928,
     'retry/count': 1598,
     'retry/max_reached': 72,
     'retry/reason_count/twisted.internet.error.TimeoutError': 1190,
     'retry/reason_count/twisted.web._newclient.ResponseNeverReceived': 408,
     'scheduler/dequeued': 2598,
     'scheduler/dequeued/memory': 2598,
     'scheduler/enqueued': 2598,
     'scheduler/enqueued/memory': 2598,
     'start_time': datetime.datetime(2023, 10, 24, 13, 10, 12, 429201)}
    

    速度不太理想用了将近15分钟,和pyspider 1/3也没区别。(0.25/32)
    同时有很多重试的,只有974个200,还有4个403的。409个重试的。剩下没有的就是重试超过次数了
    用了30M左右的代理流量

    [scrapy.core.engine] DEBUG: Crawled (403) <GET https://gnosisscan.io/tx/0xbcc31d887de7d5a35837b09e300aa532589b4f0f7144bdaf993e22526fc5c00a> (referer: None)

    好好好 0.02/100 更拉了 快是快了两分钟,重试这么多,40m流量。看来得在研究下速度的设置啊,而且这个到底

    0.25/100 竟然500个只用了 173.535025s
    但开始测试1000个又不行了,总之就是总是集中的出现timeout 要么就是先正常一段时间然后开始一直timeout
    默认设置的0/16似乎有奇效,不知道为什么,至少不会集中timeout,时间也挺快了1000个272.808858s,4分多钟,重试的也惊人的少,还几乎都是403来重试的
    好像是代理池子的问题啊,换回国内就g,国外池没啥事。
    0/32 2000个反而 645.771154
    0/100 ,这次是真的100 ,因为CONCURRENT_REQUESTS_PER_DOMAIN 、CONCURRENT_REQUESTS_PER_IP ,他们也有默认16,所以要改CONCURRENT_REQUESTS也要改了这俩,1000个76.906714s,飞一般的感觉,要是真实这个看cpu的话,在试试能不能更高,就是这个池子看是1.2倍率,1000个就用了100m,照这样52w个步得50g.
    400-51.075433s 就是会有的报错Too many open files,cpu占用率似乎没什么变化

    Too many open files

    2023-10-25 02:13:29 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://gnosisscan.io/tx/0x7c087ac812601ad32a1b7a7266b236436275b13d3cca4a19a5c7d5b1a3f35fd4> (failed 6 times): Couldn't bind: 24: Too many open files.
    

    修改系统最大文件句柄数;

    编辑sysctl.conf,添加或修改一下几个参数:

    net.ipv4.tcp_fin_timeout = 30
    net.ipv4.tcp_keepalive_intvl = 15
    net.ipv4.tcp_keepalive_time = 120
    net.ipv4.tcp_retries1 = 3
    net.ipv4.tcp_retries2 = 15
    net.ipv4.tcp_syn_retries = 6
    net.ipv4.tcp_synack_retries = 5

    保存退出并sysctl -p,使修改生效。

    sudo vim /etc/security/limits.conf
    * soft nofile 65535
    * hard nofile 65535
    etstat -natep | grep ...
    sysctl -a | grep keepalive
    sudo vim /etc/sysctl.conf

    200-65.886778s
    800 G 直接所有的都retry最大次数,神奇的是代理流量竟然没消耗,看来确实是系统问题
    大于最大限制的似乎就是先是Too many open files.,然后retry,然后要么正常要么G
    400 好好好 400现在也是直接g
    重启了照样报错,但400直接是27s了,但不太对.
    好好好100 也是Too many open files 重启!
    好好好默认954s
    100 run10000个,之前1000个正常了,试试1w,但是一段时间后又开始Too many open files.,然后retry了,看来这个真得解决啊。不过一段时间后好像又正常了,不过我手贱给停了。

    {'downloader/exception_count': 1072,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 1072,
     'downloader/request_bytes': 1923588,
     'downloader/request_count': 2084,
     'downloader/request_method_count/GET': 2084,
     'downloader/response_bytes': 19915530,
     'downloader/response_count': 1012,
     'downloader/response_status_count/200': 972,
     'downloader/response_status_count/403': 40,
     'elapsed_time_seconds': 954.680147,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 24, 20, 3, 2, 461215),
     'httpcompression/response_bytes': 144864450,
     'httpcompression/response_count': 1012,
     'item_scraped_count': 972,
     'log_count/DEBUG': 3037,
     'log_count/ERROR': 56,
     'log_count/INFO': 26,
     'memusage/max': 518320128,
     'memusage/startup': 518320128,
     'response_received_count': 972,
     'retry/count': 1084,
     'retry/max_reached': 28,
     'retry/reason_count/403 Forbidden': 40,
     'retry/reason_count/twisted.internet.error.TimeoutError': 1044,
     'scheduler/dequeued': 2084,
     'scheduler/dequeued/memory': 2084,
     'scheduler/enqueued': 2084,
     'scheduler/enqueued/memory': 2084,
     'start_time': datetime.datetime(2023, 10, 24, 19, 47, 7, 781068)}
    2023-10-25 04:03:02 [scrapy.core.engine] INFO: Spider closed (finished)

    真正解决办法:
    macOS 修改最大文件描述符、最大用户进程数 – 粽先生 – 博客园
    这样改了后400不会出现Too many open files了,但是要99.808071,可能是timeout时间给设长了.
    破案了,下面两个还是100
    真正的400 88s 甚至没快,retry还多了一倍
    1000个也没出错,不过也基本是这个速度
    3w个 300/15/20 45min 没有Too many open files但有类似的ConnectError:iledescriptor out of range in select()
    3w 200/15/20 40min/2w

    {'downloader/exception_count': 122267,
     'downloader/exception_type_count/twisted.internet.error.ConnectError': 75493,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 46774,
     'downloader/request_bytes': 140326751,
     'downloader/request_count': 149779,
     'downloader/request_method_count/GET': 149779,
     'downloader/response_bytes': 539243923,
     'downloader/response_count': 27512,
     'downloader/response_status_count/200': 26072,
     'downloader/response_status_count/403': 1439,
     'downloader/response_status_count/502': 1,
     'elapsed_time_seconds': 2730.134651,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 25, 5, 46, 41, 764645),
     'httpcompression/response_bytes': 3968139510,
     'httpcompression/response_count': 27511,
     'httperror/response_ignored_count': 2,
     'httperror/response_ignored_status_count/403': 1,
     'httperror/response_ignored_status_count/502': 1,
     'item_scraped_count': 26072,
     'log_count/DEBUG': 171934,
     'log_count/ERROR': 7853,
     'log_count/INFO': 58,
     'memusage/max': 836255744,
     'memusage/startup': 518406144,
     'response_received_count': 26074,
     'retry/count': 119779,
     'retry/max_reached': 3927,
     'retry/reason_count/403 Forbidden': 1438,
     'retry/reason_count/twisted.internet.error.ConnectError': 71726,
     'retry/reason_count/twisted.internet.error.TimeoutError': 46615,
     'scheduler/dequeued': 149779,
     'scheduler/dequeued/memory': 149779,
     'scheduler/enqueued': 149779,
     'scheduler/enqueued/memory': 149779,
     'start_time': datetime.datetime(2023, 10, 25, 5, 1, 11, 629994)}
    twisted.internet.error.ConnectError: An error occurred while connecting: [Failure instance: Traceback: <class 'ValueError'>: filedescriptor out of range in select()
    twisted.internet.error.TimeoutError: User timeout caused connection failure.

    300/15/10 开始正常,然后就是一直An error occurred while connecting: Failure instance: Traceback: <class ‘ValueError’>: filedescriptor out of range in select()
    ctrl+c之后又开始正常,直到关闭

    即使是200和100,也会最终进入filedescriptor out of range in select(),只不过是时间长短的问题,并且出现后连正常浏览器的网页也访问不了,是不是因为这种占用、连接是累积的、并没有被切断

    filedescriptor out of range in select()

    python socket select 错误 Filedescriptor out of range in select 解决方法-CSDN博客

    【精选】scrapy回调函数中使用异步请求_the installed reactor (twisted.internet.selectreac-CSDN博客
    在setting.py中加入

    TWISTED_REACTOR = 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'

    上面好像不太是,但好像没啥问题,毕竟也不知道选个啥
    twisted.internet

    400 全跑的重试很多,改成两百

    200/8/5

    {'downloader/exception_count': 1080082,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 1080074,
     'downloader/exception_type_count/twisted.web._newclient.ResponseFailed': 2,
     'downloader/exception_type_count/twisted.web._newclient.ResponseNeverReceived': 6,
     'downloader/request_bytes': 1435467020,
     'downloader/request_count': 1519024,
     'downloader/request_method_count/GET': 1519024,
     'downloader/response_bytes': 8314661952,
     'downloader/response_count': 438942,
     'downloader/response_status_count/200': 405276,
     'downloader/response_status_count/403': 22030,
     'downloader/response_status_count/502': 20,
     'downloader/response_status_count/503': 11615,
     'downloader/response_status_count/523': 1,
     'elapsed_time_seconds': 49428.030364,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 26, 4, 2, 35, 381771),
     'httpcompression/response_bytes': 57150012256,
     'httpcompression/response_count': 427306,
     'httperror/response_ignored_count': 12558,
     'httperror/response_ignored_status_count/403': 922,
     'httperror/response_ignored_status_count/502': 20,
     'httperror/response_ignored_status_count/503': 11615,
     'httperror/response_ignored_status_count/523': 1,
     'item_scraped_count': 405276,
     'log_count/DEBUG': 1824397,
     'log_count/ERROR': 200750,
     'log_count/INFO': 13393,
     'log_count/WARNING': 2,
     'memusage/max': 966774784,
     'memusage/startup': 530837504,
     'response_received_count': 417834,
     'retry/count': 1001276,
     'retry/max_reached': 100836,
     'retry/reason_count/403 Forbidden': 21108,
     'retry/reason_count/twisted.internet.error.TimeoutError': 980160,
     'retry/reason_count/twisted.web._newclient.ResponseFailed': 2,
     'retry/reason_count/twisted.web._newclient.ResponseNeverReceived': 6,
     'scheduler/dequeued': 1519024,
     'scheduler/dequeued/disk': 1519024,
     'scheduler/enqueued': 1518842,
     'scheduler/enqueued/disk': 1518842,
     'start_time': datetime.datetime(2023, 10, 25, 14, 18, 47, 351407)}
    {'downloader/exception_count': 128283,
     'downloader/exception_type_count/twisted.internet.error.TimeoutError': 128282,
     'downloader/exception_type_count/twisted.web._newclient.ResponseNeverReceived': 1,
     'downloader/request_bytes': 230844387,
     'downloader/request_count': 244291,
     'downloader/request_method_count/GET': 244291,
     'downloader/response_bytes': 2198035376,
     'downloader/response_count': 116008,
     'downloader/response_status_count/200': 106853,
     'downloader/response_status_count/403': 5675,
     'downloader/response_status_count/502': 2,
     'downloader/response_status_count/503': 3478,
     'elapsed_time_seconds': 11765.260354,
     'feedexport/success_count/FileFeedStorage': 1,
     'finish_reason': 'finished',
     'finish_time': datetime.datetime(2023, 10, 26, 8, 11, 51, 848034),
     'httpcompression/response_bytes': 15258012138,
     'httpcompression/response_count': 112528,
     'httperror/response_ignored_count': 3498,
     'httperror/response_ignored_status_count/403': 18,
     'httperror/response_ignored_status_count/502': 2,
     'httperror/response_ignored_status_count/503': 3478,
     'item_scraped_count': 106853,
     'log_count/DEBUG': 349629,
     'log_count/ERROR': 3070,
     'log_count/INFO': 3705,
     'memusage/max': 673079296,
     'memusage/startup': 207122432,
     'response_received_count': 110351,
     'retry/count': 132414,
     'retry/max_reached': 1544,
     'retry/reason_count/403 Forbidden': 5657,
     'retry/reason_count/twisted.internet.error.TimeoutError': 126756,
     'retry/reason_count/twisted.web._newclient.ResponseNeverReceived': 1,
     'scheduler/dequeued': 244291,
     'scheduler/dequeued/disk': 244291,
     'scheduler/enqueued': 244291,
     'scheduler/enqueued/disk': 244291,
     'start_time': datetime.datetime(2023, 10, 26, 4, 55, 46, 587680)}

    重试的原因

    看了一下403也不多,更多的是超时

    raise TimeoutError(f"Getting {url} took longer than {timeout} seconds.")
    twisted.internet.error.TimeoutError: User timeout caused connection failure: Getting https://gnosisscan.io/tx/0x495b3f02d4844b2086b4bb6cbd905c91c550662fdc7cdc86fc5e28e42800f7be took longer than 3.0 seconds..

    或者莫名代理出问题了

    2023-10-25 00:21:56 [scrapy.downloadermiddlewares.retry] DEBUG: Retrying <GET https://gnosisscan.io/tx/0xee3c2657b0b0ae393d00c14290b8896742aeb33e3a477ece73d29f5582a759f1> (failed 1 times): Could not open CONNECT tunnel with proxy tunnel1.docip.net:19614 [{'status': 503, 'reason': b'Service Unavailable'}]
    DEBUG: Retrying <GET https://gnosisscan.io/tx/0x3e36cfdaee208d97976d8d5dafbf8f9f2e36fce9f373e26864770ab7b5989e46> (failed 1 times): [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'ssl3_get_record', 'wrong version number')]>]

    HTTP status code is not handled or not allowed http响应状态码0,好像和ssl验证什么的有关
    TCP connection timed out: 60: Operation timed out.tcp连接超时
    status’: 407, ‘reason’: b’Account is suspended 代理平台的问题,找客服解决了

    有结果为空的(重定向)
    绝大多数数据都正常但有两行的某个数据’,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,’并且这个之前见过(没处理好时)
    还有两行只有几个有数据并且是[<Selector xpath='//*[@class="hash-tag text-truncate hash-tag-custom-from tooltip-address"]/text()' data='0xa631ab30a0a32b612c6024fa57625bd89b8...'>]这种没处理过的
    破案了,这就是之前的,它的结果如果输出的是同一个位置的文件不是覆盖而是加上去
    所以结果基本没有问题

    |´・ω・)ノ
    ヾ(≧∇≦*)ゝ
    (☆ω☆)
    (╯‵□′)╯︵┴─┴
     ̄﹃ ̄
    (/ω\)
    ∠( ᐛ 」∠)_
    (๑•̀ㅁ•́ฅ)
    →_→
    ୧(๑•̀⌄•́๑)૭
    ٩(ˊᗜˋ*)و
    (ノ°ο°)ノ
    (´இ皿இ`)
    ⌇●﹏●⌇
    (ฅ´ω`ฅ)
    (╯°A°)╯︵○○○
    φ( ̄∇ ̄o)
    ヾ(´・ ・`。)ノ"
    ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
    (ó﹏ò。)
    Σ(っ °Д °;)っ
    ( ,,´・ω・)ノ"(´っω・`。)
    ╮(╯▽╰)╭
    o(*////▽////*)q
    >﹏<
    ( ๑´•ω•) "(ㆆᴗㆆ)
    😂
    😀
    😅
    😊
    🙂
    🙃
    😌
    😍
    😘
    😜
    😝
    😏
    😒
    🙄
    😳
    😡
    😔
    😫
    😱
    😭
    💩
    👻
    🙌
    🖕
    👍
    👫
    👬
    👭
    🌚
    🌝
    🙈
    💊
    😶
    🙏
    🍦
    🍉
    😣
    Source: github.com/k4yt3x/flowerhd
    颜文字
    Emoji
    小恐龙
    花!