ZBLOG

import scrapy import time from ..items import JournalsItem, JournalsDetailItem, JournalCoverItem from scrapy.linkextractors import LinkExtractor # from scrapy_selenium import SeleniumRequest from selenium import webdriver from selenium.webdriver.c...

这个代码中可能有两个原因导致无法爬取到 parse_detail 中的数据:

  1. 在调用 SeleniumRequest 时,没有将当前页面的 HTML 内容传递给 HtmlResponse 对象。这会导致在 parse_detail 中使用 XPath 无法获取到页面元素。

解决方法:可以通过下面的代码在 parse_detail 方法中创建一个新的 HtmlResponse 对象,并将当前页面的 HTML 内容传递给它。

html = driver.page_source.encode('utf-8')
response_obj = scrapy.http.HtmlResponse(url=driver.current_url, body=html)

然后,就可以使用 response_obj.xpath() 方法来提取页面元素了。

  1. 在等待元素可见时,使用了错误的 XPath 表达式。这可能导致等待超时或者找不到目标元素。

解决方法:建议首先手动打开需要爬取的网页,在浏览器中检查需要提取的元素,然后复制其 XPath 表达式并粘贴到代码中。另外,也可以尝试使用其他定位方式(如 CSS Selector 等)来定位目标元素。

修改后的代码如下所示:

import scrapy
import time
from ..items import JournalsItem, JournalsDetailItem, JournalCoverItem
from scrapy.linkextractors import LinkExtractor
from scrapy_selenium import SeleniumRequest
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait


class CnkiSpider(scrapy.Spider):
    name = 'cnki'
    allowed_domains = ['navi.cnki.net']
    start_urls = ['https://navi.cnki.net/knavi/journals/index']
    PAGE_MAX = 290 # only 290 pages of journals have an impact factor

    def __init__(self):
        self.driver = webdriver.Chrome()

    def parse(self, response):
        self.driver.get(response.url)

        time.sleep(2)
        self.driver.find_element(By.XPATH,'//*[@id="rightnavi"]/ul/li[2]/a')
        time.sleep(5)
        html = self.driver.page_source.encode('utf-8')
        response_obj = scrapy.http.HtmlResponse(url=self.driver.current_url, body=html)

        for journal in response_obj.xpath('//div[@class="detials"]'):
            ji = JournalsItem()
            ji['name'] = journal.xpath('.//h1/text()').extract_first().strip()
            ji['composite_if'] = journal.xpath('.//p/text()').extract_first().strip()
            yield ji

            
        le = LinkExtractor(restrict_xpaths='//ul[@class="list_tup"]/li/a[@target="_blank"]')
        d_urls = le.extract_links(response)
        for d_url in d_urls: 
            yield SeleniumRequest(url=d_url.url, callback=self.parse_detail,
                                wait_time=10,
                                wait_sleep=2,)
    
    def parse_detail(self, response):
        driver = response.request.meta['driver']

        # 创建新的 HtmlResponse 对象
        html = driver.page_source.encode('utf-8')
        response_obj = scrapy.http.HtmlResponse(url=driver.current_url, body=html)

        # 等待目标元素可见
        wait = WebDriverWait(driver, 10)
        
        # 使用正确的 XPath 表达式
        wait.until(ec.visibility_of_all_elements_located((By.XPATH, '//img[@class="el-image__inner el-image__preview"]')))
        
        # 释放驱动程序
        response.release_driver()
        
        jd_item = JournalsDetailItem()
        jd_item['name'] = response_obj.xpath('//h3[@class="titbox titbox1"]/text()').extract_first().strip()
        jd_item['institute'] = response_obj.xpath('//ul[@id="JournalBaseInfo"]/li/span/text()').extract_first().strip()
        jd_item['total_publications'] = response_obj.xpath('//ul[@id="publishInfo"]/li/span/text()').extract_first().strip()
        
        yield jd_item
    
    def close(self, reason):
        self.driver.quit()

需要注意的是,代码中的 SeleniumRequest 类需要从 scrapy_selenium 模块中导入。另外,在等待目标元素可见时,要确保使用正确的 XPath 表达式或其他定位方式来定位目标元素。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=848

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?