【问题标题】:How to associate allowed_domains with start_urls in scrapy如何在scrapy中将allowed_domains与start_urls相关联
【发布时间】:2020-04-27 09:21:59
【问题描述】:

我有一个广泛的 scrapy 爬虫,它需要一个大约 20,000 行的 csv 文件。该文件有一个名称、start_url 和允许的域列。见下文:

Name               start_url               allowed_domain
place1             https://place1.co.uk    place1.co.uk
place2             https://place2.co.uk    place2.co.uk
place3             https://place3.co.uk    place3.co.uk

我的爬虫代码示例如下:

class FinalSpider(CrawlSpider): 

    name = "final"
    df = pd.read_csv("places.csv")
    start_urls = df["start_url"].values.tolist()

    custom_settings = {
        'DOWNLOAD_DELAY': 3,
        'DOWNLOADER_MIDDLEWARES': {
                'my_spider.middlewares.MySpiderDownloaderMiddleware': 543,
        },
        'SCHEDULER_PRIORITY_QUEUE': 'scrapy.pqueues.DownloaderAwarePriorityQueue',
        'CONCURRENT_REQUESTS': 100,
        'CONCURRENT_REQUESTS_PER_DOMAIN': 1,
        'RETRY_ENABLED': False,
        'AJAXCRAWL_ENABLED': True
    }

    rules = (Rule(LinkExtractor(allow_domains=(df["allowed_domain"].values.tolist())), callback='parse_item', follow=True),)


    def __init__(self):
        pass

    def parse_item(self, response):
        # do stuff

问题是我的爬虫可以跟踪任何允许域中的链接,而不仅仅是与 start_url 关联的链接。

【问题讨论】:

    标签: python-3.x web-scraping scrapy


    【解决方案1】:

    您不能为start_urls 中的每个链接分配allowed_domain

    您必须在DownloaderMiddleware 的process_request 方法中过滤网址

    这是你的蜘蛛代码

    class FinalSpider(CrawlSpider): 
    
        name = "final"
    
        custom_settings = {
            'DOWNLOAD_DELAY': 3,
            'DOWNLOADER_MIDDLEWARES': {
                    'my_spider.middlewares.MySpiderDownloaderMiddleware': 543,
            },
            'SCHEDULER_PRIORITY_QUEUE': 'scrapy.pqueues.DownloaderAwarePriorityQueue',
            'CONCURRENT_REQUESTS': 100,
            'CONCURRENT_REQUESTS_PER_DOMAIN': 1,
            'RETRY_ENABLED': False,
            'AJAXCRAWL_ENABLED': True
        }
    
        rules = (Rule(LinkExtractor(), follow=True),)
    
        def start_requests(self):
            df = pd.read_csv("places.csv")
            for key, row in df.iterrows():
                yield Request(url=row['start_url'],
                    callback=self.parse_item,
                    meta={'allowed_domain': row['allowed_domain']})
    

    这是中间件代码

    import tldextract
    from scrapy.exceptions import IgnoreRequest
    
    class MySpiderDownloaderMiddleware(object): 
    
        def process_request(self, request, spider):
            site = tldextract.extract(request.url)
            site = "{}.{}".format(site.domain, site.suffix)
    
            if request.meta['allowed_domain'] not in site:
                raise IgnoreRequest("Filtered offsite request")
    

    【讨论】:

      猜你喜欢
      • 2015-02-24
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      相关资源
      最近更新 更多