Scrapy: включить элементы с кодом статуса 404 при отправке в базу данных по конвейеру. - PullRequest
0 голосов
/ 11 декабря 2018

Используя Scrapy в среде Python 2.x, у меня есть паук, настроенный для очистки списка веб-страниц, в частности, чтобы посмотреть, не выдает ли какая-либо из этих страниц ошибку, такую ​​как 400/404/500.

Я написал проект scrapy с намерением сохранить все полученные результаты в базе данных MySQL через конвейер.И это работает!Я могу успешно писать в свою базу данных.Но только с успешно обработанными страницами, с HTTP-кодом состояния 200.

Кажется, что Scrapy не передает информацию на 404 страницах по конвейеру и в базу данных.

Ниже приведено извлечение изкод паука, который очищает две несуществующие веб-страницы:

class LandingPage004Spider(scrapy.Spider):
name='LandingPage004Spider'
start_urls = []

def __init__(self):
    super(LandingPage004Spider,self).__init__()
    #self.start_urls = unique_landingpages
    self.start_urls = ['https://www.google.com/doesntexist', 'https://www.google.com/deadpage']

def parse(self, response):
    url = response.url
    url_title = 'Title goes here.'
    pagesize = len(response.body)
    HTTP_code = response.status
    yield {'url': url, "pagesize": pagesize, "HTTP_code": HTTP_code}

Когда я запускаю этого паука, я получаю следующий вывод:

[scrapy] DEBUG: Ignoring response <404 https://www.google.com/deadpage>: HTTP status code is not handled or not allowed
[scrapy] DEBUG: Ignoring response <404 https://www.google.com/doesntexist>: HTTP status code is not handled or not allowed

Теперь я сделалнекоторые усердно занимаются этим, и кажется, что это нарочно, и есть способ заставить скрап включить 404.Я вижу, что есть опция, dont_filter , но я могу только найти инструкции о том, как добавить этот код к синтаксису кода, похожему на: yield Request (url = "test.com", callback = self.callback, dont_filter= True)

Но структура моего паука, похоже, не допускает такой строки.

Правильно ли я понимаю, что 404 не отправляются в базу данных, по замыслу?Есть ли способ добавить мой текущий код, чтобы разрешить запись 404-х?

В случае, если это поможет, вот файл pipelines.py:

from sqlalchemy.orm import sessionmaker
from LandingPageVerifier.models import LandingPagesScrapeResults, db_connect

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.engine import create_engine

Base = declarative_base()

class Landingpageverifier004Pipeline(object):
    def __init__(self):
        """
        Initializes database connection and sessionmaker.
        """
        engine = db_connect()
        self.Session = sessionmaker(bind=engine)

def process_item(self, item, spider):
    session = self.Session()
    landingpage_scrape_results = LandingPagesScrapeResults()
    landingpage_scrape_results.url = item["url"]
    landingpage_scrape_results.client_id = 1
    landingpage_scrape_results.HTTP_code = item["HTTP_code"]
    landingpage_scrape_results.page_size = item["pagesize"]

    try:
        session.add(landingpage_scrape_results)
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

    return item

и выдержка из моегоФайл models.py:

class LandingPagesScrapeResults(Base):
    __tablename__ = 'landingpages_scrape_results'
    id = Column(Integer(), primary_key=True)
    client_id = Column(Integer(), ForeignKey('landingpages_clients.id'))
    url = Column(String(512), nullable=True)
    url_shortener = Column(String(32), nullable=True)
    url_title = Column(String(256), nullable=True)
    page_size = Column(Integer(), nullable=True)
    created_on = Column(DateTime(),default=datetime.datetime.now)
    HTTP_code = Column(String(4), nullable=True)
    err_small = Column(String(1), nullable=True)
    err_has_not_found = Column(String(1), nullable=True)
    err_has_error = Column(String(1), nullable=True)
    err_has_nolongeravailable  = Column(String(1), nullable=True)
    err_no_service_specials = Column(String(1), nullable=True)

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

@ stranac, конечно, дал отличный ответ, но вы также можете обработать его напрямую с помощью атрибута errback Request, который будет перехватывать все плохие ответы, особенно в запросе, который вам нужен:

def parse(self, response):
    yield Request(
        'http://httpbin.org/status/404', 
        errback=self.parse_error, 
        callback=self.parse_item,
    )

def parse_error(self, failure):
    if failure.value.response.status == 404:
        # insert item as a bad response

def parse_item(self, response):
    # insert item as good response

Или вы, конечно, всегда можете использовать Middleware, чтобы перехватывать любые ответы / запросы сразу после их получения.

0 голосов
/ 11 декабря 2018

Из документов HttpErrorMiddleware :

Согласно стандарту HTTP, успешными являются ответы, чьи коды состояния находятся в диапазоне 200-300.

Если вы все еще хотите обработать коды ответов за пределами этого диапазона, вы можете указать, какие коды ответов может обрабатывать паук, используя атрибут handle_httpstatus_list spider или HTTPERROR_ALLOWED_CODES.

Например, если вы хотитеspider для обработки 404 ответов вы можете сделать это:

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]

Ключ handle_httpstatus_list Request.meta также можно использовать для указания того, какие коды ответов разрешить для каждого запроса.Вы также можете установить мета-ключ handle_httpstatus_all на True, если хотите разрешить любой код ответа для запроса.

Однако имейте в виду, что обрабатывать не-200 ответов обычно плохо, если вы действительно не знаете, что делаете.

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