【问题标题】:Scrapy: how to store url_id along with the crawled dataScrapy:如何将 url_id 与抓取的数据一起存储
【发布时间】:2019-03-27 09:29:26
【问题描述】:
from scrapy import Spider, Request
from selenium import webdriver

class MySpider(Spider):
    name = "my_spider"

    def __init__(self):
        self.browser = webdriver.Chrome(executable_path='E:/chromedriver')
        self.browser.set_page_load_timeout(100)


    def closed(self,spider):
        print("spider closed")
        self.browser.close()

    def start_requests(self):
        start_urls = []
        with open("target_urls.txt", 'r', encoding='utf-8') as f:
            for line in f:
                url_id, url = line.split('\t\t')
                start_urls.append(url)

        for url in start_urls:
            yield Request(url=url, callback=self.parse)

    def parse(self, response):
        yield {
            'target_url': response.url,
            'comments': response.xpath('//div[@class="comments"]//em//text()').extract()
        }

上面是我的scrapy代码。我使用scrapy crawl my_spider -o comments.json 来运行爬虫。

您可能会注意到,对于我的每个url,都有一个唯一的url_id 与之关联。如何将每个爬取的结果与url_id 匹配。理想情况下,我想将url_id 存储在comments.json 的产量输出结果中。

非常感谢!

【问题讨论】:

  • 另一个问题是,在我的输出文件comments.json中,target_urlstart_urls中的输入url不一样,有没有办法让target_url存储原始url?

标签: python python-3.x scrapy scrapy-pipeline


【解决方案1】:

例如尝试传入meta参数。我已经对您的代码进行了一些更新:

def start_requests(self):
    with open("target_urls.txt", 'r', encoding='utf-8') as f:
        for line in f:
            url_id, url = line.split('\t\t')
            yield Request(url, self.parse, meta={'url_id': url_id, 'original_url': url})

def parse(self, response):
    yield {
        'target_url': response.meta['original_url'],
        'url_id': response.meta['url_id'],
        'comments': response.xpath('//div[@class="comments"]//em//text()').extract()
    }

【讨论】:

    【解决方案2】:

    回答问题和评论,尝试这样的事情:

    from scrapy import Spider, Request
    from selenium import webdriver
    
    class MySpider(Spider):
        name = "my_spider"
    
        def __init__(self):
            self.browser = webdriver.Chrome(executable_path='E:/chromedriver')
            self.browser.set_page_load_timeout(100)
    
    
        def closed(self,spider):
            print("spider closed")
            self.browser.close()
    
        def start_requests(self):
    
            with open("target_urls.txt", 'r', encoding='utf-8') as f:
                for line in f:
                    url_id, url = line.split('\t\t')
    
                    yield Request(url=url, callback=self.parse, meta={'url_id':url_id,'url':url})
    
    
        def parse(self, response):
            yield {
            'target_url': response.meta['url'],
            'comments': response.xpath('//div[@class="comments"]//em//text()').extract(),
            'url_id':response.meta['url_id']
        }
    

    如上一个答案所说,您可以在各种方法之间传递参数,使用 META (http://scrapingauthority.com/scrapy-meta)。

    【讨论】:

    • 非常感谢,正是我需要的。但是,我会接受 vezunchik 的回答以获得更早的回复。
    猜你喜欢
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2018-11-21
    • 2017-09-04
    • 1970-01-01
    • 2019-03-17
    相关资源
    最近更新 更多