Scrapy - 连接以非干净的方式丢失。跨域

时间:2018-01-18 20:11:12

标签: python python-2.7 web-scraping scrapy python-requests

我创建了一个基本蜘蛛来从totaljobs.com中抓取一小部分工作列表。我已经设置了一个带有单个起始URL的蜘蛛,以显示我感兴趣的作业列表。从那里,我为每个结果页面启动一个单独的请求。在每个请求中,我发起一个单独的请求,回调一个不同的解析方法,以处理各个作业URL。

我发现,起始网址和所有结果页面请求都得到了很好的处理 - scrapy连接到网站并返回页面内容。但是,当它尝试跟踪每个单独作业页面的URL时,scrapy无法形成连接。在我的日志文件中,它声明:

[<twisted.python.failure.Failure twisted.internet.error.ConnectionLost: Connection to the other side was lost in a non-clean fashion: Connection lost.>]

我担心我没有大量的编程经验或互联网协议等知识。所以请原谅我无法提供有关这里可能发生的事情的更多信息。我试过改变TLS连接类型;更新到scrapy,twisted和OpenSSL的最新版本;回滚到先前版本的scrapy,twisted和OpenSSL;回滚加密版本,创建自定义Context Factory并尝试各种浏览器代理和代理。我每次都得到相同的结果:每当URL与特定的作业页面相关时,scrapy都无法连接,我得到上面的日志文件输出。

对于经验丰富的刮刀,我可能会忽略一些非常明显的东西,这会妨碍我与scrapy联系。我试过在这些主题中遵循一些建议:

https://github.com/scrapy/scrapy/issues/1429

https://github.com/requests/requests/issues/4458

https://github.com/scrapy/scrapy/issues/2717

然而,其中一些有点过头了,例如:如何更新密码列表等我认为这是某种认证问题,但是再次scrapy能够连接到该域上的其他URL,所以我不知道。

我用来测试它的代码非常基本,但无论如何它都在这里:

import scrapy

class Test(scrapy.Spider):


    start_urls = [
                    'https://www.totaljobs.com/job/welder/jark-wakefield-job79229824'
                    ,'https://www.totaljobs.com/job/welder/elliott-wragg-ltd-job78969310'
                    ,'https://www.totaljobs.com/job/welder/exo-technical-job79019672'
                    ,'https://www.totaljobs.com/job/welder/exo-technical-job79074694'
                        ]

    name = "test"

    def parse(self, response):
        print 'aaaa'
                yield {'a': 1}

以上代码中的网址未成功连接。

以下代码中的网址已成功连接。

import scrapy

class Test(scrapy.Spider):


    start_urls = [
                    'https://www.totaljobs.com/jobs/permanent/welder/in-uk'
                    ,'https://www.totaljobs.com/jobs/permanent/mig-welder/in-uk'
                    ,'https://www.totaljobs.com/jobs/permanent/tig-welder/in-uk'
                        ]

    name = "test"

    def parse(self, response):
        print 'aaaa'
                yield {'a': 1}

如果有人可以复制这种行为(或者不是视情况而定),那就太好了,让我知道。如果我需要提交更多详细信息,请与我们联系。我道歉,如果我忽视了一些非常明显的事情。我正在使用:

Windows 7 64位

Python 2.7

scrapy版本1.5.0

扭曲版本17.9.0

openSSL版本17.5.0

lxml版本4.1.1

3 个答案:

答案 0 :(得分:0)

您可以尝试设置用户代理,看看是否会改变用途。

您也可能尝试在他们之间或使用代理进行更大延迟的请求。

由于这是一个就业网站,我想他们有一些反刮机制。

这不是一个惊人的答案,但我可以与您分享一些见解,以帮助您找出接下来的步骤。

答案 1 :(得分:0)

这是我最近阅读的关于使用 Scrapy 进行负责任网页抓取的blog的链接。希望它有用

答案 2 :(得分:0)

在我的情况下,这是由于用户代理被拒绝引起的。我们应该为每个请求更改用户代理。为此,您应该使用scrapy fake user agent,然后使用此中间件来确保它在每次重试中都会更改用户代理。

from scrapy.downloadermiddlewares.retry import *
from scrapy.spidermiddlewares.httperror import *

from fake_useragent import UserAgent

class Retry500Middleware(RetryMiddleware):

    def __init__(self, settings):
        super(Retry500Middleware, self).__init__(settings)

        fallback = settings.get('FAKEUSERAGENT_FALLBACK', None)
        self.ua = UserAgent(fallback=fallback)
        self.ua_type = settings.get('RANDOM_UA_TYPE', 'random')

    def get_ua(self):
        '''Gets random UA based on the type setting (random, firefox…)'''
        return getattr(self.ua, self.ua_type)

    def process_response(self, request, response, spider):
        if request.meta.get('dont_retry', False):
            return response
        if response.status in self.retry_http_codes:
            reason = response_status_message(response.status)
            request.headers['User-Agent'] = self.get_ua()
            return self._retry(request, reason, spider) or response
        return response

    def process_exception(self, request, exception, spider):
        if isinstance(exception, self.EXCEPTIONS_TO_RETRY) \
                and not request.meta.get('dont_retry', False):
            request.headers['User-Agent'] = self.get_ua()
            return self._retry(request, exception, spider)