Как найти текущий start_url в Scrapy CrawlSpider? - PullRequest
0 голосов
/ 10 сентября 2018

При запуске Scrapy из собственного скрипта, который загружает URL-адреса из БД и следит за всеми внутренними ссылками на этих сайтах, я сталкиваюсь с жалостью. Мне нужно знать, какой start_url используется в настоящее время, так как я должен поддерживать согласованность с базой данных (SQL DB). Но: когда Scrapy использует встроенный список, называемый start_urls, чтобы получить список ссылок, по которым нужно перейти, и эти веб-сайты имеют немедленное перенаправление, возникает проблема. Например, когда запускается Scrapy и сканируется start_urls, а сканер отслеживает все находящиеся там внутренние ссылки, позже я могу определить только посещаемый в настоящее время URL-адрес, а не start_url, с которого начинался Scrapy.

Другие ответы из Интернета неверны, для других случаев использования или устарели, поскольку в прошлом году в коде Scrapy, по-видимому, произошли изменения.

MWE:

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess

class CustomerSpider(CrawlSpider):
    name = "my_crawler"
    rules = [Rule(LinkExtractor(unique=True), callback="parse_obj", ), ]

    def parse_obj(self, response):
        print(response.url)  # find current start_url and do something

a = CustomerSpider
a.start_urls = ["https://upb.de", "https://spiegel.de"]  # I want to re-identify upb.de in the crawling process in process.crawl(a), but it is redirected immediately  # I have to hand over the start_urls this way, as I use the class CustomerSpider in another class
a.allowed_domains = ["upb.de", "spiegel.de"]

process = CrawlerProcess()

process.crawl(a)
process.start()

Здесь я предоставляю MWE, где Scrapy (мой сканер) получает список URL, как я должен это сделать. Пример URL-адреса перенаправления: https://upb.de, который перенаправляет на https://uni -paderborn.de .

Я ищу элегантный способ справиться с этим, поскольку хочу использовать многочисленные функции Scrapy, такие как параллельное сканирование и т. Д. Таким образом, я не хочу использовать что-то вроде библиотеки запросов дополнительно. Я хочу найти Scrapy start_url, который в настоящее время используется внутри (в библиотеке Scrapy). Я ценю вашу помощь.

1 Ответ

0 голосов
/ 12 сентября 2018

В идеале вы должны установить свойство meta для исходного запроса и ссылаться на него позже в обратном вызове. К сожалению, CrawlSpider не поддерживает пропуск meta через Rule (см. # 929 ).

Лучше создать собственного паука, чем создавать подклассы CrawlSpider. Начните с передачи вашего start_urls в качестве параметра process.crawl, что делает его доступным в качестве свойства экземпляра. В методе start_requests выведите новый Request для каждого URL, включая ключ базы данных в виде значения meta.

Когда parse получит ответ от загрузки вашего URL-адреса, запустите на нем LinkExtractor и выдайте запрос для каждого из них на индивидуальную очистку. Здесь вы можете снова передать meta, передав исходный ключ базы данных по цепочке.

Код выглядит так:

from scrapy.spiders import Spider
from scrapy import Request
from scrapy.linkextractors import LinkExtractor
from scrapy.crawler import CrawlerProcess


class CustomerSpider(Spider):
    name = 'my_crawler'

    def start_requests(self):
        for url in self.root_urls:
            yield Request(url, meta={'root_url': url})

    def parse(self, response):
        links = LinkExtractor(unique=True).extract_links(response)

        for link in links:
            yield Request(
                link.url, callback=self.process_link, meta=response.meta)

    def process_link(self, response):
        print {
            'root_url': response.meta['root_url'],
            'resolved_url': response.url
        }


a = CustomerSpider
a.allowed_domains = ['upb.de', 'spiegel.de']

process = CrawlerProcess()

process.crawl(a, root_urls=['https://upb.de', 'https://spiegel.de'])
process.start()

# {'root_url': 'https://spiegel.de', 'resolved_url': 'http://www.spiegel.de/video/'}
# {'root_url': 'https://spiegel.de', 'resolved_url': 'http://www.spiegel.de/netzwelt/netzpolitik/'}
# {'root_url': 'https://spiegel.de', 'resolved_url': 'http://www.spiegel.de/thema/buchrezensionen/'}
...