#python #html #scrapy
#python #HTML #scrapy
Вопрос:
(Я новичок в scrapy).
Контекст
Предположим, есть сайт https://example.com
, и я хочу его очистить.
Он структурирован следующим образом:
<body>
<ul>
<li>
title_foo
<a href="https://example.com/title_foo">a desription</a>
</li>
<li>
title_bar
<a href="https://example.com/title_bar">an another desription</a>
</li>
</ul>
</body>
перейдя по <a>
ссылке, я могу получить описание, которое мне нужно перед созданием моих элементов, и отправить их в мой конвейер, который сохранит их в моей БД.
Например, допустим, что когда я следую https://example.com/title_foo , я возвращаю это описание в
<div class="a-descrption">
a description
</div>
В items.py
, я:
class MyItem(scrapy.Item):
title = scrapy.Field()
description = scrapy.Field()
И мой паук должен выглядеть так:
import scrapy
from scrapy_project.items import MyItem
class MySpider(scrapy.Spider):
name = "my_spider"
def start_requests(self):
urls = [
'https://example.com',
]
for url in urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
for li in response.xpath('//li/text()').getall()
yield {"title": li }
По крайней мере, я надеюсь, что я не тестировал это, поправьте меня, если что-то не так.
Вопрос
Здесь есть своего рода механизм «ожидания». Я имею в виду, мне нужно сказать scrapy, чтобы он подождал, пока эта ссылка будет посещена, прежде чем выдавать мой элемент. Кажется, это распространенная проблема, и я уверен, что для решения этой проблемы существуют некоторые методы, но я не смог найти, как это сделать.
Как вы это делаете?
Ответ №1:
В вашем примере единственное очищенное поле title
, так что я не совсем уверен, но похоже, что вы хотите очистить title
at https://example.com , сделайте запрос на страницу сведений (например https://example.com/title_foo ) очистите описание там, а ЗАТЕМ yield
элемент как с помощью, так description
и title
с помощью .
Если это так, общим решением для проблем такого типа является использование cb_kwargs или meta . (cb_kwargs — рекомендуемое решение, если вы используете Scrapy версии v1.7 )
cb_kwargs
позволяет передавать произвольные данные в функцию обратного вызова запроса. Важно отметить, что данные передаются как аргумент ключевого слова. Так, например:
class MySpider(scrapy.Spider):
name = "my_spider"
start_urls = ['https://example.com',]
def parse(self, response):
for li in response.xpath('//li'):
title = li.xpath('text()').get()
url_to_detail_page = li.xpath('a/@href').get()
yield scrapy.Request(
url=url_to_detail_page,
callback=self.parse_detail_page,
cb_kwargs={
'title': title
})
def parse_detail_page(self, response, title): # Notice title as a keyword arg
description = response.xpath('//div[@class="a-descrption"]//text()').getall()
yield {
'title': title,
'description': description,
}
Здесь данные, полученные на первой странице, сохраненные в title
, «сопровождают» запрос на страницу сведений и при вызове функции обратного вызова title
принимаются в качестве аргумента, поэтому вы можете получить к ним доступ из функции.