scrapy翻页失败
非专业学生,因论文研究学习爬虫技术,大部分代码都是靠gpt帮忙完成,但这个翻页gpt也弄不出来
想要爬取https://wjk.hnftp.gov.cn/policy.html?potency=4%E8%BF%99%E4%B8%AA%E7%BD%91%E7%AB%99%E7%9A%84%E6%94%BF%E5%BA%9C%E6%94%BF%E7%AD%96%E6%96%87%E6%9C%AC%EF%BC%8C
下图为网页翻页区,无论在哪一页,网站url都不变,就是上面那个。
不同的页面点击“下一页”,对应的xpath也不一样。我在第一页的“下一页”xpath为//[@id="page"]/div[1]/a[6];第二页的“下一页”xpath为//[@id="page"]/div[1]/a[9];第三页的“下一页”xpath为//*[@id="page"]/div[1]/a[10]……
但他们element都是一样的,不知道这条信息有没有用。下一页 >
下面是我在gpt帮助下搞的代码,不知道为什么,同一页节点信息会返回两次。翻页一直都不成功,请求帮助
import logging
import scrapy#用于编写爬虫的库,提供了高效的数据抓取框架
#selenium:一个用于自动化浏览器的工具,可模拟用户与网页交互,适用于处理动态内容的网页
from selenium import webdriver
#webdriver:通过Selenium控制浏览器进行自动化操作
#By:Selenium用来查找页面元素的定位方式之一
from selenium.webdriver.common.by import By
#Service:用于管理和启动Chrome浏览器的服务
from selenium.webdriver.chrome.service import Service
#ChromeDriverManager:自动管理并下载Chrome浏览器驱动的工具
from webdriver_manager.chrome import ChromeDriverManager
#time:用来控制程序的延时(例如,等待页面加载完毕)
import time
from difang.items import DifangItem
logging.basicConfig(level=logging.WARNING)
class HngovSpider(scrapy.Spider):
name = "hngov"
#2.检查修改allowed_domains
allowed_domains = ["hnftp.gov.cn"]
#1.修改start_urls
start_urls = ["https://wjk.hnftp.gov.cn/policy.html?potency=4"]
def __init__(self, *args, **kwargs):
super(HngovSpider, self).__init__(*args, **kwargs)
#初始化Selenium WebDriver
options = webdriver.ChromeOptions()
options.add_argument('--headless')
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
def parse(self, response):
#用Selenium加载网页
self.driver.get(response.url)
#等待页面加载完成,最多等待10秒
time.sleep(5)
#提取数据
#获取所有政策节点列表
node_list = self.driver.find_elements(By.XPATH,'//*[@id="policy_list_ul"]/div')
#输出节点数量
print(f"Found {len(node_list)} policy nodes.")
#创建一个item对象用于保存数据
for node in node_list:
item = DifangItem()
#获取政策名称,直接选择<a>标签
name = node.find_element(By.XPATH,'.//a').text
item['name'] = name
#获取政策链接URL,选择<a>标签的href属性
link = node.find_element(By.XPATH,'.//a').get_attribute('href')
item['link'] = link#使用Selenium的get_attribute获取链接
#获取政策类型
type = node.find_element(By.XPATH,'.//div[2]/p/span[1]').text
item['type'] = type
#获取政策有效性
valid = node.find_element(By.XPATH, './/div[2]/p/span[2]').text
item['valid'] = valid
#获得政策发布日期
date = node.find_element(By.XPATH, './/div[3]/span').text
item['date'] = date
yield item
# 查找并点击“下一页”按钮
# 查找并点击“下一页”按钮
try:
# 查找“下一页”按钮
next_button = self.driver.find_element(By.XPATH, "//*[contains(@href, 'javascript:next()')]")
if next_button:
# 点击“下一页”按钮
next_button.click()
# 等待页面加载
time.sleep(5)
# 获取新页面的HTML并传递给Scrapy进行处理
page_source = self.driver.page_source # 获取当前页面的HTML
# 使用 page_source 作为请求的body,确保 Scrapy 不重新发起新的请求,而是直接处理页面内容
yield scrapy.Request(
url=self.driver.current_url, # 使用当前URL
callback=self.parse, # 继续解析
dont_filter=True, # 不进行过滤,确保每次都会请求
body=page_source, # 传递页面HTML内容
headers={'Content-Type': 'text/html'}, # 设置请求头,确保传递HTML内容
)
else:
self.logger.info("No more pages to scrape. Stopping.")
except Exception as e:
self.logger.error(f"Next button not found or error while clicking: {e}")
