Есть ли более быстрый способ сканирования предопределенного списка URL-адресов с помощью Scrapy при необходимости предваPython

Программы на Python
Anonymous
Есть ли более быстрый способ сканирования предопределенного списка URL-адресов с помощью Scrapy при необходимости предва

Сообщение Anonymous »

У меня есть два Scrapy Spider:
  • Spider 1 сканирует список ссылок на продукты (~10 000) и сохраняет их в файл csv. с помощью корма. Он не посещает каждую из этих ссылок, а только категории (с несколькими страницами). Этот Spider редко нужно запускать, поэтому скорость здесь не является проблемой.
  • Spider 2 посещает каждую из этих ссылок и извлекает некоторую информацию о продукте, а также сохраняет ее в формате CSV. Его необходимо запускать не реже одного раза в день, поэтому скорость имеет решающее значение.
Поскольку оба посещают один и тот же веб-сайт (просто разные подстраницы), их структура аналогична. . Оба должны сначала пройти аутентификацию (многоэтапная аутентификация), поэтому я не могу просто иметь все ссылки, которые им нужны для сканирования, в start_urls. Однако, несмотря на то, что они очень похожи, Spider 1 сканирует около 500 страниц в минуту, а Spider 2 — только около 50 страниц в минуту, что очень медленно.
Единственное ключевое различие заключается в как они «обнаруживают» страницы, которые им нужно просканировать:
  • Паук 1 начинает с небольшого списка, а затем одну за другой обнаруживает другие страницы.
    Spider 2 считывает большой заранее заданный список из файла, а затем просто перебирает страницы, чтобы просканировать их.
Поскольку и то, и другое на самом деле не выполняйте никакой тяжелой обработки просканированных страниц, я предполагал, что запуск страниц в цикле, как в Spider 2 (метод after_2nd_step), не позволяет Scrapy правильно сканировать их асинхронно, но я понятия не имею, так ли это действительно так.
Еще одно мое предположение заключалось в том, что самому веб-сайту по какой-либо причине требуется больше времени для загрузки страниц с информацией о продукте. Однако я не нашел способа увидеть некоторые данные по этому вопросу, например среднее время загрузки страницы при выполнении.
Поэтому мой вопрос заключается в следующем: почему Spider 2 в 10 раз медленнее, чем Spider 1, хотя он работает на той же машине и сканирует тот же веб-сайт? Есть ли более быстрый способ сканирования длинного предопределенного списка URL-адресов в Spider 2? Если проблема не очевидна из моего кода, есть ли хороший способ проанализировать время, необходимое для загрузки страницы?
Вот мой код для них обоих, некоторые из них я анонимизировал чувствительные части, будьте уверены, что оригинал является действительным кодом Python. Я постарался сохранить большую часть, так как может быть проблема в чем-то, что мне кажется неактуальным:
# Spider 1
import scrapy
from scrapy.http import TextResponse

from product_pages import PRODUKTSEITEN # a list of ~27 predefined URLs for all the categories

class ProductLinkSpider(scrapy.Spider):
name = 'my_name'
start_urls = ['URL to login page']

custom_settings = {
'FEEDS': {
'path\\product_links.csv': {
'format': 'csv',
'encoding': 'utf8',
'overwrite': True,
},
},
}

def parse(self, response):
# First, we handle the login form
return scrapy.FormRequest.from_response(
response,
formid='loginForm',
formdata={
#entering password and username
},
callback=self.after_login
)

def after_login(self, response):
# Check for login success by verifying the response content
if "Your User ID or Password is incorrect. Please try again" in response.text:
self.logger.error("Login failed")
# 2nd login step
return scrapy.FormRequest.from_response(
response,
formxpath='//form[@action="/lorem ipsum"]',
formdata={
# Formdata is filled in
},
callback=self.after_2nd_step
)

def after_2nd_step(self, response):
for page in PRODUKTSEITEN:
yield scrapy.Request(
page+"?sort=asc&q=%3Arelevance#&page=0",
callback=self.parse_products_list_page,
cb_kwargs=dict(url_without_page=page+"?sort=asc&q=%3Arelevance", page=0)
)

def parse_products_list_page(self, response: TextResponse, url_without_page: str, page: int):
product_links = response.css('a css selector to get the links').getall()

if There is another page:
# Checks if there is another page, and requests it next
yield scrapy.Request(
url_without_page + f"&page={page+1}",
callback=self.parse_products_list_page,
cb_kwargs=dict(url_without_page=url_without_page, page=page+1)
)

for link in product_links:
yield {"url": link}

И для второго Паука:
# Spider 2
import scrapy
from scrapy.http import TextResponse

class ProductInfoSpider(scrapy.Spider):
name = 'lorem ipsum'
start_urls = ['login page']
custom_settings = {
'FEEDS': {
'path\\product_info_added_2.csv': {
'format': 'csv',
'encoding': 'utf8',
'overwrite': True,
},
},
}

def parse(self, response):
# First, we handle the login form
return scrapy.FormRequest.from_response(
response,
formid='loginForm',
formdata={
# Enter username and password
},
callback=self.after_login
)

def after_login(self, response):
# Check for login success by verifying the response content
if "Your User ID or Password is incorrect. Please try again" in response.text:
self.logger.error("Login failed")

return scrapy.FormRequest.from_response(
response,
formxpath='//form[@action="/lorem ipsum"]',
formdata={
# Enter the same data as in the first Spider
},
callback=self.after_2nd_step
)

def after_2nd_step(self, response):
with open(r"path\product_links.csv", "r") as file:
# HERE is the only key difference
lines = file.readlines()
product_links = lines[1:]
for link in product_links:
yield scrapy.Request("domain"+link, callback=self.parse_product_page)

def parse_product_page(self, response):
# extract some info about the product using 4 different css selectors to get the data
yield {Some of the extracted info, 6 columns}


Подробнее здесь: https://stackoverflow.com/questions/790 ... hen-having

Вернуться в «Python»