我遇到了Scrapy的传呼困难。 我通常会成功使用以下代码
next_page = response.xpath("//div//div[4]//ul[1]//li[10]//a[1]//@href").extract_first()
if next_page is not None:
yield scrapy.Request(url = response.urljoin(next_page), callback=self.parse)
事实证明,在这种尝试中,我遇到了一个使用5页块的网站。参见下图。
因此,在捕获了前5页之后,Scrapy跳到倒数第二页(526)。
分页结构遵循以下逻辑:
https://www.example.com-1-data.html
并且它在数值上增加。 有人可以通过分页的增量查询(基于示例地址)帮助我吗?
答案 0 :(得分:3)
关于分页,最佳方法实际上取决于所使用的分页类型。
如果您:
page
表示您在哪个页面上然后,您可以一次安排所有页面:
def parse_listings_page1(self, response):
"""
here parse first page, schedule all other pages at once!
"""
# e.g. 'http://shop.com/products?page=1'
url = response.url
# e.g. 100
total_pages = int(response.css('.last-page').extract_first())
# schedule every page at once!
for page in range(2, total_pages + 1):
page_url = add_or_replace_parameter(url, 'page', page)
yield Request(page_url, self.parse_listings)
# don't forget to also parse listings on first page!
yield from self.parse_listings(response)
def parse_listings(self, response):
for url in response.css('.listing::attr(href)'):
yield Request(url, self.parse_product)
此方法的巨大好处是速度-在这里,您可以采用异步逻辑并同时抓取所有页面!
或者。
如果您:
然后,您必须按1:1同步安排页面。
def parse(self, response):
for product in response.css('.product::attr(href)'):
yield Request(product, self.parse_product)
next_page = response.css('.next-page::attr(href)').extract_first()
if next_page:
yield Request(next_page, self.parse)
else:
print(f'last page reached: {response.url}')
在您的示例中,您使用第二种同步方法并且您在这里的担心是没有根据的,您只需要确保xpath选择器选择正确的页面即可。
答案 1 :(得分:1)
要从所有导航页提取所有数据,可以在规则中使用Scrapy LinkExtractor。
1使用RegExp
rules = {
Rule(LinkExtractor(allow='.*part-of-url/page-nav/page.*'), callback='parse_page', follow=True)
}
2使用XPath
rules = {
Rule(LinkExtractor(allow=(), restrict_xpaths='//ul[@class="nav-block"]'), callback='parse_page', follow=True)
}