Scrapy - проанализируйте страницу для извлечения предметов - затем следуйте и сохраните содержимое URL -адреса.
Вопрос
У меня есть вопрос о том, как сделать это в скраске. У меня есть паук, который ползет для перечисления страниц предметов. Каждый раз, когда встречается страница листинга, с элементами существует обратный вызов parse_item (), который требуется для извлечения данных и получения элементов. Пока все хорошо, все отлично работает.
Но каждый элемент имеет среди других данных, URL, с более подробной информацией об этом элементе. Я хочу следовать этому URL и сохранить в другом поле предметов (url_contents) извлеченное содержимое URL -адреса этого элемента.
И я не уверен, как организовать код для достижения этого, поскольку две ссылки (ссылка на списки и одна ссылка на элемент) соблюдается по -разному, с обратными вызовами в разное время, но я должен сопоставить их в одном и том же обработке элемента Анкет
Мой код пока выглядит так:
class MySpider(CrawlSpider):
name = "example.com"
allowed_domains = ["example.com"]
start_urls = [
"http://www.example.com/?q=example",
]
rules = (
Rule(SgmlLinkExtractor(allow=('example\.com', 'start='), deny=('sort='), restrict_xpaths = '//div[@class="pagination"]'), callback='parse_item'),
Rule(SgmlLinkExtractor(allow=('item\/detail', )), follow = False),
)
def parse_item(self, response):
main_selector = HtmlXPathSelector(response)
xpath = '//h2[@class="title"]'
sub_selectors = main_selector.select(xpath)
for sel in sub_selectors:
item = ExampleItem()
l = ExampleLoader(item = item, selector = sel)
l.add_xpath('title', 'a[@title]/@title')
......
yield l.load_item()
Решение
После некоторого тестирования и мышления я нашел это решение, которое работает для меня. Идея состоит в том, чтобы использовать только первое правило, которое дает вам списки элементов, а также, очень важно, добавить следующий = верный к этому правилу.
А в parse_item () вы должны получить запрос вместо элемента, но после загрузки элемента. Запрос должен подробно описан URL. И вы должны отправить загруженный элемент в этот обратный вызов запроса. Вы выполняете свою работу с ответом, и есть, где вы даете элемент.
Таким образом, отделка parse_item () будет выглядеть следующим образом:
itemloaded = l.load_item()
# fill url contents
url = sel.select(item_url_xpath).extract()[0]
request = Request(url, callback = lambda r: self.parse_url_contents(r))
request.meta['item'] = itemloaded
yield request
А затем parse_url_contents () будет выглядеть следующим образом:
def parse_url_contents(self, response):
item = response.request.meta['item']
item['url_contents'] = response.body
yield item
Если у кого -то есть другой (лучший) подход, дайте нам знать.
Стефан
Другие советы
Я сижу с той же проблемой, и из-за того, что никто не ответил на ваш вопрос в течение 2 дней, я считаю, что единственное решение-следовать этому URL-адресу вручную, из вашего parse_item
функция
Я новичок в скраске, поэтому я бы не стал попытаться это с этим (хотя я уверен, что это возможно), но мое решение будет использовать urllib
и BeautifulSoup, чтобы загрузить вторую страницу вручную, извлечь эту информацию сам и сохранить ее как часть элемента. Да, гораздо больше проблем, чем скрара, делает нормальный анализ, но он должен выполнить работу с наименьшей хлопот.