Scrapy: как сохранить url_id вместе с данными обхода

#python #python-3.x #scrapy #scrapy-pipeline

#python #python-3.x #scrapy #scrapy-конвейер

Вопрос:

 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('tt')
                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 в результате вывода yield в comments.json .

Большое спасибо!

Комментарии:

1. Другой вопрос в том, что в моем выходном файле comments.json , target_url не совпадает с входным URL в start_urls , есть ли способ разрешить target_url сохранять исходный URL?

Ответ №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('tt')
            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('tt')

                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).

Комментарии:

1. Большое спасибо, именно то, что мне нужно. Тем не менее, я бы принял ответ везунчика за более ранний ответ.