Очистка страницы внутри страницы иногда не попадает на вторую страницу - PullRequest
0 голосов
/ 12 июня 2018

Я использую здесь следующего Паука:

import scrapy

questions = {}

class SovSpider(scrapy.Spider):
    name = 'StackOverflow'
    allowed_domains = ['stackoverflow.com']
    start_urls = ['https://stackoverflow.com/questions']

    def parse(self, response):
        for link in response.css('a.question-hyperlink::attr(href)').extract():

            yield scrapy.Request(url=response.urljoin(link), callback=self.parse_questions)

            yield scrapy.Request(url=response.urljoin(response.css('a[rel="next"]::attr(href)').extract_first()), callback=self.parse)


    def parse_questions(self, response):
        questions["title"] = response.css('a.question-hyperlink::text').extract_first()
        questions["user"] = response.css('.user-details a::text').extract_first()

        yield scrapy.Request(url=response.urljoin(response.css('.user-details a::attr(href)').extract_first()), callback=self.parse_user)

        yield questions

    def parse_user(self, response):
        questions["user_reputation"] = response.css('div.reputation::text').extract_first().strip()

пытаюсь Practice Очистка страницы, затем получение URL с той же страницыОчистить свою страницу [Page1(Scraped) -[Page1[Url-Inside]]> Page2(Scrape)]

Паук делает следующее:

  1. Очистка Questions Page URL

  2. Соскоб Question Title Со страницы, введенной URLs

  3. Соскоб User Reputation Со страницы пользователя, введенной Scraped URL из Question

Так, например, мой вопрос здесь должен дать мне следующее:

{"title": "Scraping a Page within a Page sometimes doesn't enter the second Page", "user": "Toleo", "user_reputation": 455}

Проблема в том, что почти 3/ 4 очищенных элементов возвращает только parse_question часть, подобную этой

{"title": "Scraping a Page within a Page sometimes doesn't enter the second Page", "user": "Toleo"}

А иногда нет. В чем здесь проблема?

1 Ответ

0 голосов
/ 12 июня 2018

Проблема заключается в том, что вы выдаете запрос на parse_user одновременно с выдачей questions, но Item и Request обрабатываются различными промежуточными программами, поэтому они не будут выполняться один за другим.

Лучше отправьте первую часть вопросов на parse_user, используя мета, и получите только questions в parse_user

def parse_questions(self, response):
    questions = {}

    questions["title"] = response.css('a.question-hyperlink::text').extract_first()
    questions["user"] = response.css('.user-details a::text').extract_first()

    yield scrapy.Request(url=response.urljoin(response.css('.user-details a::attr(href)').extract_first()),
                         callback=self.parse_user,
                         meta={'questions': questions})

def parse_user(self, response):
    questions = response.meta.get('questions')
    questions["user_reputation"] = response.css('div.reputation::text').extract_first().strip()
    yield questions

Вам лучше создать новую переменную questions на каждомвызов parse_questions, как указано выше, поскольку он не должен быть глобальной переменной.

Более того, следует исправить parse следующим образом

def parse(self, response):
    for link in response.css('a.question-hyperlink::attr(href)').extract():

        yield scrapy.Request(url=response.urljoin(link), callback=self.parse_questions)

    yield scrapy.Request(url=response.urljoin(response.css('a[rel="next"]::attr(href)').extract_first()), callback=self.parse)

Поскольку вы выдаете запрос на следующую страницудля каждой ссылки на одной странице, что не так проблематично, потому что скрапирование, как дупфильтр, но, вероятно, будет более эффективным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...