Code Monkey home page Code Monkey logo

ru-scrapy-python's Introduction

made-with-markdown Chat GitHub stars GitHub contributors

В этом репозитории находится полезная информация, собранная участниками чата.

С чего начать?

Как ограничить количество реквестов?

  • CLOSESPIDER_PAGECOUNT = 10
  • И там же рядом полезные настройки вида: CLOSESPIDER_ITEMCOUNT, CLOSESPIDER_ERRORCOUNT, CLOSESPIDER_TIMEOUT, CLOSESPIDER_TIMEOUT_NO_ITEM

Как спарсить данные из JS?

  • смотреть откуда идут данные в Chrome -> devtools -> network -> XHR
  • JS to Python
  • Официальная документация рекомендует
  • ставится Splash(удобно в Docker) и плагин scrapy_splash (устарело)
  • Сейчас широко поддерживается и используется scrapy-playwright, под windows работает только из-под WSL2.

Лучшие практики

  • Использовать css селекторы чтобы избежать пробелов в названии при использовании @class в xpath, альтернатива "contains(@class, 'someclass')" выглядит сложнее.
  • Использовать xpath для поиска сложных значений, например в таблицах
  • Использовать корутины или asyncio для синхронных запросов в функции. Добавлен пример с asyncio.
  • Посмотреть мобильную версию

Популярные css селекторы

Пример xpath селекторов, которые обычно не вытащишь через css-селекторы

  • Получить предка от текущего элемента, например: response.xpath('./ancestor::a[contains(@class, "class_name")]/@href
  • Комментарии html, например: response.xpath('.//ul[@class="class_name"]/comment()[contains(.,"Артикул")]').get()

Полезные библиотеки

  • html_text - извлечь текст из сложного селектора, аналог .get_text(' ', strip=True) из BeautifulSoup, но быстрее и точнее.

Полезные браузерные расширения

  • Selector Gadget получить короткий css или xpath элемента(ов), см. видео на их сайте. Получается намного лучше встроенного в браузер copy as css/xpath.

Нельзя мешать yield и return?

После return жизни нет. Нужно возвращать список или что-то итерируемое.

Как вытащить узел по тексту внутри него используя css-селектор

Через CSS - никак. Использовать xpath contains. Документация по xpath.

Как поставить на windows

Простой способ - поставить в anaconda

Как достать items из последнего job-а в scrapinghub?

https://app.scrapinghub.com/api/items.json?project=PROJECT&spider=SPIDERNAME&apikey=KEY там где SPIDERNAME нужно вставить именно название, а не номер паука. дополнительно можно почитать тут

Как спарсить данные из нескольких форм с POST-запросами

Использовать цикл по форме c FormRequest.from_response, дополнительное поле со счетчиком формы formnumber=counter и с фильтром dont_filter=True.

Как обойти Cloudflare?

Страница отдает 503 ошибку. На этой странице javascript собирает код в форму с рандомным урлом и тремя hidden полями. После отправки этой формы отдается 302 редирект на нужную страницу.

Как передавать cookies

При надобности в передаче заранее подготовленных (например после авторизации на сайте) cookies, осуществить это можно через свой DownloaderMiddleware так:

  • В settings.py активируйте ваши DOWNLOADER_MIDDLEWARES
  • В settings.py убедиться, что значение по умолчанию COOKIES_ENABLED = True не переопределено на False, иначе scrapy не будет сохранять передаваемые ему страницой cookies.
  • В middlewares.py в методе обработки запросов process_request вашего DownloaderMiddleware прописать что-то такое:
def process_request(self, request, spider):
    request.cookies[cookiename] = value     # вставьте ваши значения
    return None
  • COOKIES_DEBUG = True в settings.py может помочь увидеть, что же происходит.

Где найти дефолтные настройки Scrapy?

default_settings.py в офф.репо

Как проанализировать запрос/форму?

Chrome -> devtools -> network -> клик на страницу -> copy as curl. Далее гуглим "curl to python", вставляем код и получаем распаршенный код в библиотеке requests
Если в Network в браузере поставить галочку напротив preserve log, то история запросов перестает очищаться при переходах между страницами.

Чем проанализировать пакеты сети или воспроизвести запрос/форму?

Fiddler или postman(он умеет сразу в питонкод конвертить). Мощнее и сложнее wireshark.

По умолчанию скрапи обрабатывает успешные ответы, для обработки остальных ответов используйте handle_httpstatus_list, например:

class MySpider(CrawlSpider):
    handle_httpstatus_list = [404]
  • также пригождается в редких случаях, если сайт отдает ошибку, но сам при этом показывает валидные данные, а scrapy ему "верит" - ответ не 200, и не парсит.

params в scrapy

В requests можно передать дополнительные параметры в GET методе:

import requests
params = [('q', 'scrapy')]
response = requests.get('https://github.com/search', params=params)

В scrapy можно сделать аналогично, через FormRequest:

FormRequest(
    url='https://github.com/search',
    method='GET',
    formdata=params,
    callback=self.parse_data,
)

Пример синхронного запроса с использованием async/await синтаксиса:

Для одного запроса:

from scrapy.utils.defer import maybe_deferred_to_future
class SingleRequestSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ["https://books.toscrape.com"]
    start_urls = ["https://books.toscrape.com/catalogue/page-1.html"]

    async def parse(self, response, **kwargs):
        additional_request = scrapy.Request("https://books.toscrape.com/catalogue/the-black-maria_991/index.html")
        deferred = self.crawler.engine.download(additional_request)
        additional_response = await maybe_deferred_to_future(deferred)
        yield {
            "h1": response.css("h1::text").get(),
            "price": additional_response.css(".price_color::text").get(),
        }

Пример параллельных запросов с использованием asyncio:

import scrapy
from scrapy.utils.defer import maybe_deferred_to_future
import asyncio

class MultipleRequestsSpider(scrapy.Spider):
    name = "multiple"
    start_urls = ["https://books.toscrape.com/catalogue/page-1.html"]

    @classmethod
    def update_settings(cls, settings):
        settings["TWISTED_REACTOR"] = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"

    async def parse(self, response, **kwargs):
        additional_requests = [
            scrapy.Request("https://books.toscrape.com/catalogue/the-black-maria_991/index.html"),
            scrapy.Request("https://books.toscrape.com/catalogue/the-requiem-red_995/index.html"),
        ]
        coroutines = []
        for r in additional_requests:
            deferred = self.crawler.engine.download(r)
            coroutines.append(maybe_deferred_to_future(deferred))
        responses = await asyncio.gather(
            *coroutines, return_exceptions=True
        )
        yield {
            'h1': response.css('h1::text').get(),
            'price': responses[0].css('.price_color::text').get(),
            'price2': responses[1].css('.price_color::text').get(),
        }

Деплой Scrapy

  • Хостинг Scrapinghub по дефолту стоит задержка, нужно отключать в настройках AUTOTHROTTLE_ENABLED чекбокс False
  • UI для Scrapy ScrapydWeb
  • Управление Scrapyd

Тесты

На сколько Scrapy быстрый?

Проверка N страниц.

  • requests в один поток - бесконечное время
  • scrapy из локальной машины - 30 минут
  • scrapinghub с включенным по дефолту тротлингом - больше 1 часа
  • scrapinghub без троттлинга 1 юнит - 23 минуты
  • scrapinghub без троттлинга 3 юнита - 15 минут

Можно ли использовать регулярные выражения в xpath?

Да, можно

Практика по регулярным выражениям. С чего начать?

Очистка текста от HTML тегов

Исходный текст

<p>Включает:</p><p>Клапан впускной / VALVE INLET АРТ: 3142H111		3	шт</p>

Удаление HTML тегов из текста без сохранения визуального переноса строк:

from w3lib.html import remove_tags
remove_tags(text)
Включает:Клапан впускной / VALVE INLET АРТ: 3142H111		3	шт                   

Удаление тегов из текста с сохранением визуального переноса строк с помощью библиотеки html2text

import html2text
html2text.html2text(text)
Клапан впускной / VALVE INLET АРТ: 3142H111 3 шт

Полезные ресурсы по Xpath

Справочники и туториалы с примерами:

Подборка cheatsheets и bestpractices по xpath

ru-scrapy-python's People

Contributors

bulatbulat48 avatar dervedro avatar mifody avatar scrapuseren avatar serhii73 avatar yadalik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ru-scrapy-python's Issues

Передача params в скрапи

import requests


params = (
    ('q', 'scrapy'),
)

response = requests.get('https://github.com/search', params=params)

так мы передаем запрос в реквесте.
но как, это переписать в скрапи, я не совсем понял.

Написал вот такое решение, которое подходит.

        return FormRequest(url='https://github.com/search',
                           method='GET',
                           headers=headers,
                           formdata=params,
                           callback=self.parse_data)

Думаю, что необходимо это отобразить в ридми.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.