Я создал скрипт в scrapy, чтобы анализировать author name различных сообщений с его целевой страницы, а затем передавать его методу parse_page, используя ключевое слово meta, чтобы одновременно печатать post content вместе с author name.
Я использовал download_slot в мета-ключевом слове, которое якобы маскирует ускорение работы скрипта. Хотя нет необходимости следовать логике, которую я пытался применить здесь, я хотел бы придерживаться ее только для того, чтобы понять, как download_slot работает в любом скрипте и почему. Я много искал, чтобы узнать больше о download_slot, но в итоге нашел несколько ссылок, таких как Вот этот.
Пример использования download_slot (хотя я не совсем в этом уверен):
from scrapy.crawler import CrawlerProcess
from scrapy import Request
import scrapy
class ConventionSpider(scrapy.Spider):
name = 'stackoverflow'
start_urls = ['https://stackoverflow.com/questions/tagged/web-scraping']
def parse(self,response):
for link in response.css('.summary'):
name = link.css('.user-details a::text').extract_first()
url = link.css('.question-hyperlink::attr(href)').extract_first()
nurl = response.urljoin(url)
yield Request(nurl,callback=self.parse_page,meta = {'item':name,"download_slot":name})
def parse_page(self,response):
elem = response.meta.get("item")
post = ' '.join([item for item in response.css("#question .post-text p::text").extract()])
yield {'Name':elem,'Main_Content':post}
if __name__ == "__main__":
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/5.0',
})
process.crawl(ConventionSpider)
process.start()
Приведенный выше скрипт работает безупречно.
My question: how
download_slotworks within scrapy?






Начнем с Скребковая архитектура. Когда вы создаете scrapy.Request, механизм Scrapy передает запрос загрузчику на получение содержимого. Загрузчик помещает входящие запросы в слоты, которые вы можете представить как независимые очереди запросов. Затем опрашиваются очереди, и обрабатывается каждый отдельный запрос (контент загружается).
А теперь самая важная часть. Чтобы определить, в какой слот поместить входящий запрос, загрузчик проверяет request.meta на наличие ключа download_slot. Если он присутствует, он помещает запрос в слот с этим именем (и создает его, если он еще не существует). Если ключ download_slot отсутствует, он помещает запрос в слот для домена (точнее, имени хоста), на который указывает URL-адрес запроса.
Это объясняет, почему ваш скрипт работает быстрее. Вы создаете несколько слотов для загрузчиков, потому что они основаны на имени автора. Если бы вы этого не сделали, они были бы помещены в один и тот же слот в зависимости от домена (который всегда stackoverflow.com). Таким образом, вы эффективно увеличиваете параллелизм загрузки контента.
Это объяснение немного упрощено, но оно должно дать вам представление о том, что происходит. Вы можете сами проверить код.
Например, есть какой-то целевой веб-сайт, который позволяет обрабатывать только 1 запрос в 20 секунд, и нам нужно разобрать/обработать 3000 веб-страниц с данными о продуктах с него.
Обычный паук с настройкой DOWNLOAD_DELAY на 20 - приложение завершит работу примерно через 17 часов (3000 pages * 20 seconds задержка загрузки).
Если у вас есть цель увеличить скорость парсинга без бана веб-сайтом, и у вас есть, например, 20 действительных прокси, вы можете равномерно распределить URL-адреса запросов для всех ваших прокси, используя мета-ключ proxy и download_slot, и значительно сократить время выполнения заявки.
from scrapy.crawler import CrawlerProcess
from scrapy import Request
import scrapy
class ProxySpider(scrapy.Spider):
name = 'proxy'
start_urls = ['https://example.com/products/1','https://example.com/products/2','....']#list with 3000 products url
proxies = [',,,'] #list wiht 20 proxies
def start_requests(self):
for index, url in start_urls:
chosen_proxy = proxies(index % len(self.proxies)
yield Request(url, callback=self.parse,
meta = {"proxy":chosen_proxy,"download_slot":chosen_proxy})
def parse(self,response):
....
yeild item
#yield Request(deatails_url,
callback=self.parse_additional_details,
meta=
{"download_slot":response.request.meta["download_slot"],
"proxy":response.request.meta["download_slot"]})
if __name__ == "__main__":
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/5.0','DOWNLOAD_DELAY':20, "COOKIES_ENABLED":False
})
process.crawl(ProxySpider)
process.start()
Я предлагаю вам задать новый вопрос со всем контекстом и деталями, чтобы каждый мог ответить.