我使用下面的代码来抓取一个网页:
import scrapy
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, NoSuchElementException, StaleElementReferenceException
class JornaleconomicoSpider(scrapy.Spider):
name = 'jornaleconomico'
allowed_domains = ['jornaleconomico.pt']
start_urls = ['https://jornaleconomico.pt/categoria/economia']
def parse(self, response):
options = Options()
driver_path = '###' #Your Chrome Webdriver Path
browser_path = '###' #Your Google Chrome Path
options.binary_location = browser_path
options.add_experimental_option("detach", True)
self.driver = webdriver.Chrome(options=options, executable_path=driver_path)
self.driver.get(response.url)
ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
wait = WebDriverWait(self.driver, 120, ignored_exceptions=ignored_exceptions)
self.new_src = None
self.new_response = None
i=0
while i<10:
# click next link
try:
element = wait.until(EC.element_to_be_clickable((By.XPATH, '*//div[@class="je-btn je-btn-more"]')))
self.driver.execute_script("arguments[0].click();", element)
self.new_src = self.driver.page_source
self.new_response = response.replace(body=self.new_src)
i += 1
except TimeoutException:
self.logger.info('No more pages to load.')
self.driver.quit()
break
# grab the data
headlines = self.new_response.xpath('*//h1[@class="je-post-title"]/a/text()').extract()
for headline in headlines:
yield {
'text': headline
}
上面的代码应该在Ver迈斯artigos上单击10次(* 查看更多文章 *)并获取所有标题的文本,但它只获取前九个原始标题。我检查了Chrome Selenium上的页面源代码(使用options.add_experimental_option("detach", True)
行冻结Selenium窗口),而且我算出了页面源和原始页面是一样的,对我来说,这不应该发生,因为在同一个Selenium窗口中,我可以正确地检查所有文章,而不仅仅是前九篇文章,即使使用WebDriveWait
也不能防止这种情况发生。如何解决这个问题?
2条答案
按热度按时间eqfvzcg81#
以下是(几乎)完整的解决方案:
输出如下所示:
5gfr0r5j2#
你实际上并不需要使用Selenium这个非常容易获取的网站。如果我需要从那里获取数据,我会这样做。
与 Postman 测试
博客的前9条记录与链接一起打印,分页可以使用上面的 Postman 示例来完成,只需将“je_offset”更改为[9,18,27等]并更新“nonce”。
每次你加载页面时,你需要从html中获取新的“nonce”,这是网站在每个页面上显示的内容,尝试使用re.search获取“ AJAX _nonce”值。
尝试使用requests.get加载页面,使用www.example.com分页requests.post-这会让你的工作变得超级简单,比selenium快得多。