使用Scrapy+Selenium爬取arp.fr仅获取12条数据如何爬取全部内容
问题原因
- 列表页未经过Selenium渲染,无法提取商品链接:你当前代码中Scrapy默认下载器请求列表页,拿到的是未执行JS的原始HTML,不存在你规则中指定的商品链接元素,仅能提取到第一页的12条商品链接,这也是你只能爬到12条的核心原因。
- 详情页提取XPath写死,无法适配所有商品:你
parse_item中写的XPath匹配固定title="028001007"的属性,仅对应某一个特定商品,其余商品爬取后都会返回空值,无法统计到有效数据。 - 分页范围配置不足:站点共487条商品,每页展示12条,总共有约41页,你当前仅配置了前5页的请求,就算全部爬取成功也拿不到全量数据。
- Selenium配置不完善易被反爬拦截:你导入了
selenium_stealth但没有实际调用,也没有开启无头模式,爬虫特征明显,很容易被站点拦截导致请求失败。
修复方案
- 重写
start_requests方法,列表页统一用Selenium渲染后再交给规则提取链接 - 替换详情页的固定XPath为通用匹配规则,可根据实际页面结构调整路径
- 调整分页范围覆盖全量数据,完善Selenium的反爬配置
- 替换固定
sleep为显式等待,提升爬取效率
修改后参考代码
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from shutil import which from scrapy.selector import Selector from selenium_stealth import stealth import time class CpcuSpider(CrawlSpider): name = 'cp' allowed_domains = ['www.arp.fr'] # 调整分页范围到总页数,487/12≈41,所以range到42 start_urls = [ 'https://www.arp.fr/produits-portables-tablettes-ordinateurs-portables/?queryString=JTdCJTIyYXJlYUlkJTIyJTNBJTIyMkVEODhGMjctOTNFOS00NzQzLUI3NDYtRUNFQUJENUZFRDA4JTIyJTJDJTIyaXNRdWVyeSUyMiUzQWZhbHNlJTJDJTIyc29ydEF0dHJpYnV0ZSUyMiUzQW51bGwlMkMlMjJzb3J0RGlyZWN0aW9uJTIyJTNBbnVsbCUyQyUyMnBhZ2VubyUyMiUzQSUyMjElMjIlMkMlMjJwZXJQYWdlJTIyJTNBJTIyMTIlMjIlMkMlMjJ2YWx1ZXMlMjIlM0ElNUIlNUQlMkMlMjJwcm9kdWN0SWRzJTIyJTNBJTVCJTVEJTJDJTIycGFydG5lcklkJTIyJTNBbnVsbCUyQyUyMm9wdGlvbnMlMjIlM0ElNUJudWxsJTJDbnVsbCUyQ251bGwlNUQlN0Q=&page='+str(x)+'&productfilter=&sort=null' for x in range(1,42)] rules = ( Rule(LinkExtractor(restrict_xpaths='//a[@class="rasEpicTitle rasElementReaction"]'), callback='parse_item', follow=False), ) def __init__(self): CrawlSpider.__init__(self) chrome_options = Options() # 开启无头模式,后台运行 chrome_options.add_argument("--headless=new") chrome_options.add_argument("--start-maximized") chrome_options.add_argument("--disable-blink-features=AutomationControlled") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option("useAutomationExtension", False) chrome_path = which("chromedriver") self.driver = webdriver.Chrome(executable_path=chrome_path, options=chrome_options) # 调用stealth隐藏爬虫特征 stealth(self.driver, languages=["fr-FR", "fr"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) def start_requests(self): # 列表页用Selenium渲染后再返回response给规则处理 for url in self.start_urls: self.driver.get(url) # 等待商品列表元素加载完成 WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.XPATH, '//a[@class="rasEpicTitle rasElementReaction"]')) ) time.sleep(1) yield scrapy.Request(url, callback=self.parse, dont_filter=True) def parse_item(self, response): self.driver.get(response.url) # 等待标题元素加载完成,可替换为实际页面的标题元素定位规则 WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'h1')) ) page_source = Selector(text=self.driver.page_source) # 替换为通用的标题XPath,不要写死属性值 yield{ 'Title': page_source.xpath('//h1/text()').get().strip() } def closed(self, reason): # 爬虫结束后关闭driver,避免资源泄漏 self.driver.quit()
内容的提问来源于stack exchange,提问作者user16704247
相关产品推荐
相关产品推荐

