Я пытаюсь очистить информацию о продукте с веб-страницы с помощью scrapy. Моя веб-страница, которую нужно очистить, выглядит так:
- начинается со страницы product_list с 10 продуктами
- нажатие на кнопку "Далее" загружает следующие 10 продуктов (URL-адрес между двумя страницами не меняется)
- Я использую LinkExtractor, чтобы переходить по каждой ссылке продукта на страницу продукта и получать всю необходимую информацию
Я попытался воспроизвести ajax-call следующей кнопки, но не могу работать, поэтому я пробую селен. Я могу запустить selenium webdriver в отдельном скрипте, но я не знаю, как интегрироваться с scrapy. Куда мне поместить селен в мой паук для скрапинга?
Мой паук довольно стандартный, вроде следующего:
class ProductSpider(CrawlSpider):
name = "product_spider"
allowed_domains = ['example.com']
start_urls = ['http://example.com/shanghai']
rules = [
Rule(SgmlLinkExtractor(restrict_xpaths='//div[@id="productList"]//dl[@class="t2"]//dt'), callback='parse_product'),
]
def parse_product(self, response):
self.log("parsing product %s" %response.url, level=INFO)
hxs = HtmlXPathSelector(response)
# actual data follows
Любая идея приветствуется. Спасибо!
Ответ 1 · рейтинг 131 · alecxe
Это действительно зависит от того, как вам нужно очистить сайт и как и какие данные вы хотите получить.
Вот пример того, как вы можете следить за разбивкой на страницы на ebay, используя _1 _ + _ 2_:
import scrapy
from selenium import webdriver
class ProductSpider(scrapy.Spider):
name = "product_spider"
allowed_domains = ['ebay.com']
start_urls = ['http://www.ebay.com/sch/i.html?_odkw=books&_osacat=0&_trksid=p2045573.m570.l1313.TR0.TRC0.Xpython&_nkw=python&_sacat=0&_from=R40']
def __init__(self):
self.driver = webdriver.Firefox()
def parse(self, response):
self.driver.get(response.url)
while True:
next = self.driver.find_element_by_xpath('//td[@class="pagn-next"]/a')
try:
next.click()
# get the data and write it to scrapy items
except:
break
self.driver.close()
Вот несколько примеров "селеновых пауков":
Существует также альтернатива использованию Selenium с Scrapy. В некоторых случаях использования ScrapyJS промежуточного программного обеспечения достаточно для обработки динамических частей страницы. Пример использования в реальном мире:
Ответ 2 · рейтинг 4 · muhive
Если (URL-адрес не меняется между двумя страницами), тогда вы должны добавить dont_filter = True с вашим scrapy.Request () или scrapy найдет этот URL-адрес как дубликат после обработки первой страницы.
Если вам нужно отображать страницы с помощью javascript, вы должны использовать scrapy-splash, вы также можете проверить это промежуточное программное обеспечение scrapy, которое может обрабатывать javascript страницы, использующие селен, или вы можете сделать это, запустив любой безголовый браузер
Но более эффективное и быстрое решение - проверить свой браузер и посмотреть, какие запросы выполняются во время отправки формы или запуска определенного события. Попробуйте смоделировать те же запросы, которые отправляет ваш браузер. Если вы сможете правильно воспроизвести запросы, вы получите нужные данные.
Вот пример:
class ScrollScraper(Spider):
name = "scrollingscraper"
quote_url = "http://quotes.toscrape.com/api/quotes?page="
start_urls = [quote_url + "1"]
def parse(self, response):
quote_item = QuoteItem()
print response.body
data = json.loads(response.body)
for item in data.get('quotes', []):
quote_item["author"] = item.get('author', {}).get('name')
quote_item['quote'] = item.get('text')
quote_item['tags'] = item.get('tags')
yield quote_item
if data['has_next']:
next_page = data['page'] + 1
yield Request(self.quote_url + str(next_page))
Когда URL-адрес разбивки на страницы одинаков для всех страниц и использует запрос POST, вы можете использовать scrapy.FormRequest () вместо scrapy.Request (), оба одинаковы, но FormRequest добавляет новый аргумент (formdata =) конструктора.
Вот еще один пример паука из этого сообщения:
class SpiderClass(scrapy.Spider):
# spider name and all
name = 'ajax'
page_incr = 1
start_urls = ['http://www.pcguia.pt/category/reviews/#paginated=1']
pagination_url = 'http://www.pcguia.pt/wp-content/themes/flavor/functions/ajax.php'
def parse(self, response):
sel = Selector(response)
if self.page_incr > 1:
json_data = json.loads(response.body)
sel = Selector(text=json_data.get('content', ''))
# your code here
# pagination code starts here
if sel.xpath('//div[@class="panel-wrapper"]'):
self.page_incr += 1
formdata = {
'sorter': 'recent',
'location': 'main loop',
'loop': 'main loop',
'action': 'sort',
'view': 'grid',
'columns': '3',
'paginated': str(self.page_incr),
'currentquery[category_name]': 'reviews'
}
yield FormRequest(url=self.pagination_url, formdata=formdata, callback=self.parse)
else:
return