scrapy+selenium 如何在完成一个页面列表后抓取不同的页面列表?
scrapy+selenium how to crawl a different page list once i'm done with one?
我正在尝试从“action/user 交易”网站抓取数据,它是意大利语的,所以我会尽量清楚。
我对 Python 和 Scrapy 也很陌生,这是我的第一个项目。
该网站没有一个简单的方法来关注 links,所以我不得不想出一些办法。
首先,我转到总列表,其中列出了所有页面,这非常简单,因为第一页是“https://www.subito.it/annunci-italia/vendita/usato/?o=1”,然后转到“ /?o=218776",我选择页面的第一个 link 并用 selenium 打开它,在这里我得到我需要的数据并单击“下一页”按钮,但这是棘手的部分。
如果我使用相同的 URL 转到同一页面,则没有“下一页”按钮,只有当您位于列表页面的第一个时,它才有效,然后单击该页面 link,从这里您现在可以关注其他 link。
我以为它会完成,但我错了。一般列表分为页面(.../?o=1,.../?o=2,等),每个页面都有 X 数量的链接(我没有计算它们),当你在其中一个拍卖页面(来自列表页面,因此您可以使用“下一页”按钮),然后单击“下一页”,您将按照一般列表中 link 的顺序进行操作。
更清楚的是,如果总列表有200k页,每页有50links,当你点击第一个link页时,你可以点击“下一页”49次,之后“下一页”按钮处于非活动状态,您无法转到更早的 link,您必须返回列表并转到下一页,然后重复该过程。
import scrapy
from scrapy.http import HtmlResponse
from scrapy.selector import Selector
from selenium import webdriver
class NumeriSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'https://www.subito.it/annunci-italia/vendita/usato/?o=41',
]
def __init__(self):
self.driver = webdriver.Firefox()
def parse(self, response):
self.driver.get(response.url)
self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[5]/div[2]/div[1]/div[3]/div[1]/a').click()
while True:
sel = Selector(text=self.driver.page_source)
item = {
'titolo': sel.xpath('//h1[@class= "classes_sbt-text-atom__2GBat classes_token-h4__3_Swu size-normal classes_weight-semibold__1RkLc ad-info__title"]/text()').get(),
'nome': sel.xpath("//p[@class='classes_sbt-text-atom__2GBat classes_token-subheading__3yij_ size-normal classes_weight-semibold__1RkLc user-name jsx-1261801758']/text()").get(),
'luogo': sel.xpath("//span[@class='classes_sbt-text-atom__2GBat classes_token-overline__2P5H8 size-normal ad-info__location__text']/text()").get()
}
yield item
next = self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[1]/section[1]/nav/div/div/button[2]')
try:
next.click()
except:
driver.quit()
这是我在 scrapy 文档和许多 websites/Whosebug 页面的帮助下编写的代码。
我给它一般列表的页面来抓取,在这种情况下 https://www.subito.it/annunci-italia/vendita/usato/?o=41
,它找到页面的第一个 link (self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[5]/div[2]/div[1]/div[3]/div[1]/a').click()
),然后开始获取我想要的数据。完成后,它会单击“下一页”按钮 (next = self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[1]/section[1]/nav/div/div/button[2]')
) 并重复“获取数据-单击下一页”过程。
最后一个项目页面将有一个无效的“下一页”按钮,所以在爬虫卡住的那一刻,我手动关闭浏览器,用记事本++编辑“start_urls”link作为之后的页面我刚刚抓取的那个,运行 抓取工具再次抓取此页面。
我希望它是全自动的,这样我就可以让它做几个小时的事情(我将数据保存在 json atm 文件中)。
“非活动”下一页按钮仅在 disabled=""
属性上与活动按钮不同,我该如何检测?一旦检测到,我如何告诉爬虫返回列表页面加 1 并再次执行数据抓取过程?
我的问题是只检测那个不活动的按钮并制作一个循环,将 1 添加到我给的列表页面(如果我从 link“https://www.subito.it/annunci-italia/vendita/usato/?o=1
”开始,它应该转到“https://www.subito.it/annunci-italia/vendita/usato/?o=2
” " 并做同样的事情)
可以通过覆盖 start_requests
方法在页面上进行迭代。为了达到目的,你需要写一个循环来请求所有(在本例中为 219xxx)页面并提取第二层页面 href
s.
def start_requests(self):
pages_count = 1 # in this method you need to hard code your pages quantity
for i in range(pages_count)
url = 'https://www.subito.it/annunci-italia/vendita/usato/?o=%s' % str(i + 1)
scrapy.Request(url, callback=self.parse)
或者更好的方法是找出第一层中有多少页,它总是在最后一个 class="unselected-page"
元素中,这样您就可以使用 response.xpath('//*[@class="unselected-page"]//text()').getall()[-1]
找到它。在这种情况下,您需要在第一个 parse
方法中请求第一层页面。
def start_requests(self):
base_url = 'https://www.subito.it/annunci-italia/vendita/usato'
scrapy.Request(base_url, callback=self.parse_first_layer)
def parse_first_layer(self, response):
pages_count = int(response.xpath('//*[@class="unselected-page"]//text()').getall()[-1])
for i in range(pages_count)
url = 'https://www.subito.it/annunci-italia/vendita/usato/?o=%s' % str(i + 1)
scrapy.Request(url, callback=self.parse_second_layer)
到达第一层链接后,您可以像以前一样在每个页面中迭代 50 个链接。
我正在尝试从“action/user 交易”网站抓取数据,它是意大利语的,所以我会尽量清楚。 我对 Python 和 Scrapy 也很陌生,这是我的第一个项目。 该网站没有一个简单的方法来关注 links,所以我不得不想出一些办法。 首先,我转到总列表,其中列出了所有页面,这非常简单,因为第一页是“https://www.subito.it/annunci-italia/vendita/usato/?o=1”,然后转到“ /?o=218776",我选择页面的第一个 link 并用 selenium 打开它,在这里我得到我需要的数据并单击“下一页”按钮,但这是棘手的部分。 如果我使用相同的 URL 转到同一页面,则没有“下一页”按钮,只有当您位于列表页面的第一个时,它才有效,然后单击该页面 link,从这里您现在可以关注其他 link。 我以为它会完成,但我错了。一般列表分为页面(.../?o=1,.../?o=2,等),每个页面都有 X 数量的链接(我没有计算它们),当你在其中一个拍卖页面(来自列表页面,因此您可以使用“下一页”按钮),然后单击“下一页”,您将按照一般列表中 link 的顺序进行操作。 更清楚的是,如果总列表有200k页,每页有50links,当你点击第一个link页时,你可以点击“下一页”49次,之后“下一页”按钮处于非活动状态,您无法转到更早的 link,您必须返回列表并转到下一页,然后重复该过程。
import scrapy
from scrapy.http import HtmlResponse
from scrapy.selector import Selector
from selenium import webdriver
class NumeriSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'https://www.subito.it/annunci-italia/vendita/usato/?o=41',
]
def __init__(self):
self.driver = webdriver.Firefox()
def parse(self, response):
self.driver.get(response.url)
self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[5]/div[2]/div[1]/div[3]/div[1]/a').click()
while True:
sel = Selector(text=self.driver.page_source)
item = {
'titolo': sel.xpath('//h1[@class= "classes_sbt-text-atom__2GBat classes_token-h4__3_Swu size-normal classes_weight-semibold__1RkLc ad-info__title"]/text()').get(),
'nome': sel.xpath("//p[@class='classes_sbt-text-atom__2GBat classes_token-subheading__3yij_ size-normal classes_weight-semibold__1RkLc user-name jsx-1261801758']/text()").get(),
'luogo': sel.xpath("//span[@class='classes_sbt-text-atom__2GBat classes_token-overline__2P5H8 size-normal ad-info__location__text']/text()").get()
}
yield item
next = self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[1]/section[1]/nav/div/div/button[2]')
try:
next.click()
except:
driver.quit()
这是我在 scrapy 文档和许多 websites/Whosebug 页面的帮助下编写的代码。
我给它一般列表的页面来抓取,在这种情况下 https://www.subito.it/annunci-italia/vendita/usato/?o=41
,它找到页面的第一个 link (self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[5]/div[2]/div[1]/div[3]/div[1]/a').click()
),然后开始获取我想要的数据。完成后,它会单击“下一页”按钮 (next = self.driver.find_element_by_xpath('/html/body/div[5]/div/main/div[2]/div[1]/section[1]/nav/div/div/button[2]')
) 并重复“获取数据-单击下一页”过程。
最后一个项目页面将有一个无效的“下一页”按钮,所以在爬虫卡住的那一刻,我手动关闭浏览器,用记事本++编辑“start_urls”link作为之后的页面我刚刚抓取的那个,运行 抓取工具再次抓取此页面。
我希望它是全自动的,这样我就可以让它做几个小时的事情(我将数据保存在 json atm 文件中)。
“非活动”下一页按钮仅在 disabled=""
属性上与活动按钮不同,我该如何检测?一旦检测到,我如何告诉爬虫返回列表页面加 1 并再次执行数据抓取过程?
我的问题是只检测那个不活动的按钮并制作一个循环,将 1 添加到我给的列表页面(如果我从 link“https://www.subito.it/annunci-italia/vendita/usato/?o=1
”开始,它应该转到“https://www.subito.it/annunci-italia/vendita/usato/?o=2
” " 并做同样的事情)
可以通过覆盖 start_requests
方法在页面上进行迭代。为了达到目的,你需要写一个循环来请求所有(在本例中为 219xxx)页面并提取第二层页面 href
s.
def start_requests(self):
pages_count = 1 # in this method you need to hard code your pages quantity
for i in range(pages_count)
url = 'https://www.subito.it/annunci-italia/vendita/usato/?o=%s' % str(i + 1)
scrapy.Request(url, callback=self.parse)
或者更好的方法是找出第一层中有多少页,它总是在最后一个 class="unselected-page"
元素中,这样您就可以使用 response.xpath('//*[@class="unselected-page"]//text()').getall()[-1]
找到它。在这种情况下,您需要在第一个 parse
方法中请求第一层页面。
def start_requests(self):
base_url = 'https://www.subito.it/annunci-italia/vendita/usato'
scrapy.Request(base_url, callback=self.parse_first_layer)
def parse_first_layer(self, response):
pages_count = int(response.xpath('//*[@class="unselected-page"]//text()').getall()[-1])
for i in range(pages_count)
url = 'https://www.subito.it/annunci-italia/vendita/usato/?o=%s' % str(i + 1)
scrapy.Request(url, callback=self.parse_second_layer)
到达第一层链接后,您可以像以前一样在每个页面中迭代 50 个链接。