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.com...

根据您提供的代码,我发现问题可能出在 SeleniumRequest 的使用上。

首先,由于 Scrapy-Selenium 是基于异步的 Selenium 驱动程序运行的,因此需要保证在请求时使用 yield 来返回一个生成器对象。同时,在请求回调函数中,我们也需要将 response.release_driver() 语句放在最后一行以释放资源。

其次,从您提供的代码中可以看到,您并没有正确地设置 SeleniumRequest 中的参数。比如 wait_time 和 wait_sleep 参数都应该是 wait_timewait_for_page_load。这两个参数分别用来指定等待页面加载时间和是否等待页面完全加载完成。

因此,我对您提供的代码进行了修改,并添加了必要的注释说明,请参考下面的代码:

import scrapy
import time
from ..items import JournalsItem, JournalsDetailItem, JournalCoverItem
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'
    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 = None

    def start_requests(self):
        # 初始化时打开浏览器窗口并访问起始网址
        self.driver = webdriver.Chrome()
        self.driver.get(self.start_urls[0])
        
        # 等待页面加载完成
        WebDriverWait(self.driver, 10).until(
            ec.presence_of_element_located((By.XPATH, '//*[@id="rightnavi"]/ul/li[2]/a'))
        )
        
        # 点击“影响因子”链接,跳转到包含所有期刊列表的页面
        self.driver.find_element('xpath', '//*[@id="rightnavi"]/ul/li[2]/a').click()

        # 构造 SeleniumRequest 对象并返回生成器对象
        yield SeleniumRequest(
            url=self.driver.current_url,
            callback=self.parse,
            wait_time=10,
            wait_for_page_load=True,
            meta={'driver': self.driver}
        )

    def parse(self, response):
        driver = response.request.meta['driver']

        # 将网页源代码封装成 Response 对象,便于后续的解析操作
        html = driver.page_source.encode('utf-8')
        response_obj = scrapy.http.HtmlResponse(url=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

        
        for journal_link in response_obj.xpath('//ul[@class="list_tup"]/li/a[@target="_blank"]/@href'):
            full_url = f'https://navi.cnki.net{journal_link.extract()}'
            
            # 构造 SeleniumRequest 对象并返回生成器对象
            yield SeleniumRequest(
                url=full_url,
                callback=self.parse_detail,
                wait_time=10,
                wait_for_page_load=True,
                meta={'driver': driver}
            )
    
    def parse_detail(self, response):
        driver = response.request.meta['driver']

        # 将网页源代码封装成 Response 对象,便于后续的解析操作
        html = driver.page_source.encode('utf-8')
        journal_obj = scrapy.http.HtmlResponse(url=driver.current_url, body=html)

        # 提取期刊详情信息并构造 JournalsDetailItem 对象返回
        jd_item = JournalsDetailItem()
        jd_item['name'] = journal_obj.xpath('//h3[@class="titbox titbox1"]/text()').extract_first()
        jd_item['institute'] = journal_obj.xpath('//ul[@id="JournalBaseInfo"]/li/span/text()').extract_first()
        jd_item['total_publications'] = journal_obj.xpath('//ul[@id="publishInfo"]/li/span/text()').extract_first()
        
        yield jd_item

    def closed(self, reason):
        if self.driver:
            self.driver.quit()  # 关闭浏览器窗口,释放资源

希望以上修改能够解决您的问题。如果还有其他疑问,请随时追问。

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?