Web Crawler не переходит по ссылкам - PullRequest
0 голосов
/ 06 апреля 2019

Я хочу сканировать новостной сайт, используя Scrapy. Код извлекал связанные новости из текущей ссылки, но не переходил по ссылкам следующей страницы. Новостной сайт имеет следующую ссылку

enter image description here

Код, которым я следую:

import scrapy 

class fakenews(scrapy.Spider):
    name = "bb8"
    allowed_domains = ["snopes.com"]
    start_urls = [
        "https://www.snopes.com/fact-check/category/science/"

    ]

    custom_settings = {'FEED_URI': "fakenews_%(time)s.csv",
                       'FEED_FORMAT': 'csv'}

    def parse(self, response):

        name1 = input(" Please enter input :     ")
        name1 = name1.lower()

        links =response.xpath("//div[@class='media-list']/article/a/@href").extract()
        headers = response.xpath('//div[@class="media-body"]/h5/text()').extract()
        headers1 = [c.strip().lower() for c in headers]

        raw_data=zip(headers1,links)
        for header, link in raw_data:

            p = header
            l=link
            if name1 in p:
                scrap_info3 = {'page': response.url, 'title': header, 'link':l}

                yield scrap_info3

                next_page = response.css("//a[@class='btn-next btn']/@href").get()
                if next_page is not None:
                    next_page = response.urljoin(next_page)
                    yield scrapy.Request(next_page, callback=self.parse)

Хотя с текущей страницы она возвращает информацию, но также показывает ошибку.

enter image description here

Для ввода я ввел: НАСА

1 Ответ

1 голос
/ 06 апреля 2019

Основная ошибка в том, что у вас есть css функция и xpath селектор для next_page:

next_page = response.css("//a[@class='btn-next btn']/@href").get()

Следующая проблема в том, что у вас есть запрос на следующую страницу внутри цикла for. Это приведет к большому количеству повторных запросов.

Итак, я предполагаю, что эти изменения:

def parse(self, response):
    name1 = input(" Please enter input :     ")
    name1 = name1.lower()

    links = response.xpath("//div[@class='media-list']/article/a/@href").extract()
    headers = response.xpath('//div[@class="media-body"]/h5/text()').extract()
    headers1 = [c.strip().lower() for c in headers]

    # my changes since this moment:
    raw_data = zip(headers1, links)
    # use less variables in loop (yes, just cosmetic, but your code will more readable)
    for header, link in raw_data:
        if name1 in header:
            yield {'page': response.url, 'title': header, 'link': link}

    # use proper selector here
    next_page = response.css("a.btn-next::attr(href)").get()
    # move all this block out of for loop
    if next_page:
        yield response.follow(next_page)
...