#python #html #web-scraping #scrapy
#python #HTML #веб-очистка #scrapy
Вопрос:
Я работаю с небольшим скребком, чтобы очистить несколько продуктов на странице Amazon.
В настоящее время я могу очистить (после передачи начального URL-адреса, где я ищу определенный товар):
- Названия всех продуктов на странице
- URL-адреса всех продуктов на странице
- Номер ASIN всех продуктов на странице
Но чего я не могу сделать: если вы погрузитесь в HTML-код Amazon, вы увидите, что порядок товаров отображается с помощью «search_result_X» (где X — число, поэтому 0 = первый на странице, 30 — 31-й продукт на странице и так далее).
Как я могу добавить ‘search_result_x’ (заказ) к каждому продукту?Поэтому я надеюсь получить очищенный результат следующим образом (примечание: если вы видите приведенный ниже код, единственное, чего не хватает, это Order_Number):
{'Title_Product': Title ASDF, 'Link_Product': 'www.asdf.com', 'ASIN_Product' = 'B12345689', Order_Number = '1'}, {'Title_Product': Title_2 ASDF, 'Link_Product': 'www.asdf2.com', 'ASIN_Product' = 'B12345682', Order_Number = '2'}
Итак, большой файл JSON и единственный отсутствующий столбец — это «Order_Number» столбца (порядок, в котором появился продукт.
Пока что код (извлечен из Stack и из Thiago):
import os
from twisted.internet import reactor
import scrapy
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
import re
class AmazonProductSpider(scrapy.Spider):
name = "AmazonDeals"
allowed_domains = ["amazon.com"]
#Use working product URL below
start_urls = [
"https://www.amazon.com/s?k=trimmeramp;ref=nb_sb_noss_2"]
## Check this link, could be usefull https://www.youtube.com/watch?v=JpHgsdQhsXo
custom_settings = {
'FEED_URI' : 'Asin_Titles.json',
'FEED_FORMAT' : 'json'
}
def parse(self, response):
Link = response.css('.a-text-normal').css('a::attr(href)').extract()
Title = response.css('span.a-text-normal').css('::text').extract()
OrderNumber = response.css("div::attr(data-index)").get()
# for each product, create AmazonItem, populate the fields and yield the item
for result in zip(Link,Title):
item = AmazonItem()
item['title_Product'] = result[1]
item['link_Product'] = result[0]
# Extract ASIN from link
ASIN = re.findall(r"(?<=dp/)[A-Z0-9]{10}",result[0])[0]
item['ASIN_Product'] = ASIN
item['url_Response'] = response.url
# Test to get the Order Number @
item['Order_Number'] = OrderNumber
yield item
class AmazonItem(scrapy.Item):
title_Product = scrapy.Field()
link_Product = scrapy.Field()
ASIN_Product = scrapy.Field()
url_Response = scrapy.Field()
Order_Number = scrapy.Field()
configure_logging({'LOG_FORMAT': '%(levelname)s: %(message)s'})
runner = CrawlerRunner()
d = runner.crawl(AmazonProductSpider)
d.addBoth(lambda _: reactor.stop())
reactor.run() # the script will block here until the crawling is finished
Ответ №1:
Это свойство генерируется javascript после загрузки страницы. Если вы проверите «Просмотр источника страницы» в своем браузере, вы увидите, что он не существует в теле ответа. Однако у него есть data-index
свойство, которое может вас заинтересовать. Например.
<div data-asin="B00H2B4H2M" data-index="5" class="..." ></div>
Редактировать:
И чтобы получить это, вы можете использовать что-то:
response.css("div::attr(data-index)").get()
или
response.xpath(".//div/@data-index").get()
ПРАВКА2:
Кроме того, я предлагаю вам просмотреть результаты поиска, а затем найти сведения о каждом продукте, вместо того, чтобы выбирать каждое поле и пытаться объединить их вместе. Например.
def parse(self, response):
for product in response.css('.s-result-item'):
item = AmazonItem()
item['asin'] = product.css('::attr(data-asin)').get()
item['index'] = product.css('::attr(data-index)').get()
item['link'] = product.css('.a-text-normal::attr(href)').get()
# And so on
# ...
yield item
Комментарии:
1. Спасибо @Thiago, можете ли вы помочь мне получить число «5» в вашем примере? Поскольку я пытался получить это число с помощью Xpath (используя contains), к сожалению, он запрашивает значение индекса данных .. что, конечно, необходимо.
2. Проверьте это сейчас 🙂
3. Большое вам спасибо, Тьяго! Я попытался интегрировать ваш код в свой скрипт (см. Отредактированный скрипт выше), но я получаю только number = 0 (если я запускаю скрипт). У вас есть идея, что происходит не так? Заранее большое спасибо!!
4. Это был пример, вы должны адаптировать его к правильному селектору. Смотрите мое последнее редактирование
5. Потрясающе! Спасибо!!