欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

爬虫练习(一)爬取知网、万方、维普文献标题、作者、刊物来源等信息

程序员文章站 2022-03-02 19:39:07
...

刚刚开始学习Python,今天一周整,浏览了站内一些大侠博客相关内容,自己也尝试着写了一个爬虫。

直接借鉴了几位大侠的经验,如有冒犯之处恳请海涵。

先说说目的吧,本爬虫的目的是根据EXCEL文件的作者名字信息,以及设定的单位信息来自动循环爬取文章题目、作者姓名、期刊名称、发表时间(刊次)、下载量、被引量等信息并保存到CSV文件中。

用到了chromedriver、selenium、xlrd、pandas

因为我爬取的作者发文量比较少,万方、维普部分,没有做分页查询。

因为太懒,查询函数没有做成模块,我知道这是一种不好的习惯,以后我会改(也不一定)。

三个查询函数中所用的获取目标信息的方式不是很统一。

还请大家谅解一个快40的人,写代码写的这么乱。

代码仅供大家学习交流,请勿用于违法用途,如有侵权请联系我,我会及时删除。

代码还有很多不足的地方,请大家批评指正!

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.webdriver.common.keys import Keys
import xlrd
from urllib.parse import urljoin
import time
import random
import json
import csv
import pandas as pd
from itertools import zip_longest
# 设置谷歌驱动器的环境
options = webdriver.ChromeOptions()
# 设置chrome不加载图片,提高速度
options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2})
# 创建一个谷歌驱动器
browser = webdriver.Chrome()
data_list = [] # 声明一个全局列表,用来存储字典
def start_spider(aurname):  #爬取知网信息
    # 请求url
    url = 'https://kns.cnki.net/kns/brief/result.aspx?dbprefix=SCDB&crossDbcodes=CJFQ,CDFD,CMFD,CPFD,IPFD,CCND,CCJD'
    browser.get(url)
    # 显示等待输入框是否加载完成
    WebDriverWait(browser, 1000).until(
        EC.presence_of_all_elements_located(
            (By.ID, 'iframeResult')
        )
    )
    browser.find_element_by_id('au_1_value1').send_keys(aurname)
    browser.find_element_by_id('au_1_value2').send_keys('清华大学')
    # 在input框内输入回车实现  search_btn.click()效果
    browser.find_element_by_id('txt_2_value1').send_keys(Keys.ENTER)
    # 显示等待文献是否加载完成,等待iframe加载完成
    time.sleep(5)

    browser.switch_to.default_content()
    browser.switch_to.frame('iframeResult') # 定位到页面元素


    df = []
    for page in range(1, 2):
        try:
            browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
            paper_name = browser.find_elements_by_css_selector('a.fz14')
            author = browser.find_elements_by_css_selector('td.author_flag')
            source = browser.find_elements_by_css_selector('td.author_flag+td')
            datetime = browser.find_elements_by_css_selector('td.author_flag+td+td')
            database = browser.find_elements_by_css_selector('td.author_flag+td+td+td')
            beiyin=browser.find_elements_by_css_selector('span.KnowledgeNetcont')
            download = browser.find_elements_by_css_selector('span.downloadCount')
            for k, v, m, n, q,b, w in zip_longest(paper_name, author, source, datetime, database, beiyin,download, fillvalue=0):
                if w == 0:
                    df.append([k.text, v.text, m.text, n.text, q.text,b.text, w])
                else:
                    df.append([k.text, v.text, m.text, n.text, q.text,b.text, w.text])
            print('第{}页爬取完毕'.format(page))
            browser.find_element_by_link_text('下一页').click()
            time.sleep(random.randint(2, 5))
        except:
            print('未爬到数据')
            time.sleep(5)
    time.sleep(10)
    inf=pd.DataFrame(df)
    inf.to_csv('paper_information.csv',mode='a', header=False,index=False,encoding='utf-8-sig')

#----爬取万方-------------------------#

def start_wf_spider(aurname):  #爬取万方信息
    # 请求url
    wfurl = 'http://www.wanfangdata.com.cn/searchResult/getAdvancedSearch.do?searchType=all'
    browser.get(wfurl)
    # 显示等待输入框是否加载完成
    WebDriverWait(browser, 1000).until(
        EC.presence_of_all_elements_located(
            (By.ID, 'help_div')
        )
    )
    time.sleep(1)
    browser.find_element_by_xpath("//div[@id='search_condition_input']/div/div[@class='info3']/input").send_keys(aurname)
    browser.find_element_by_xpath("//div[@name='search_condition_div'and not(@id)]/div/div[@class='info3']/input").send_keys("清华大学")
    browser.find_element_by_id('set_advanced_search_btn').click() #点击检索
    time.sleep(5) #页面加载等待
    wftitle=[]
    wflb=[]
    wfauthor=[]
    wfdownl=[]
    wfquate=[]
    wfsource=[]
    wffbtime=[]
    try:
        browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')  # 滑轮到页面底部左下角
        divs = browser.find_elements_by_xpath('//div[@class="ResultCont"]/div[@class="title"]/strong')  # 定位文献类型
        ddivs = browser.find_elements_by_xpath('//div[@class="ResultCont"]/div[@class="title"]/a')  # 定位文献名称
        authdiv = browser.find_elements_by_xpath('//div[@class="ResultCont"]/div/div[@class="author"]')  # 定位作者信息
        obdivs = browser.find_elements_by_xpath('//div[@class="use obtain"]/span/b')  # 定位下载信息
        obqdivs = browser.find_elements_by_xpath('//div[@class="use spread"]/span/b')  # 定位被引信息
        iconclicks = browser.find_elements_by_xpath('//i[@class="icon icon_Miner"]')  # 定位到含有下载及被引信息的小M图标
        sources = browser.find_elements_by_xpath('//div[@class="ResultCont"]/div/div[@class="Source"]')  # 定位期刊名称信息
        fbtimes = browser.find_elements_by_xpath('//div[@class="ResultCont"]/div/div[@class="Volume"]')  # 定位期刊刊次信息
        t = 0
        # 获取文献信息数据
        for iconclick in iconclicks:
            wfauthor.append(authdiv[t].text)
            wflb.append(divs[t].text)
            wftitle.append(ddivs[t].text)
            iconclick.click()  # 点击**M小图标
            wfdownl.append(obdivs[t].text)  # 获取下载量数据
            wfquate.append(obqdivs[t].text)  # 获取被引量数据
            wfsource.append(sources[t].text)  # 获取期刊名称
            wffbtime.append(fbtimes[t].text)  # 获取期刊刊次
            t += 1
            df = []
            for k, v, m, n, q, b, w in zip_longest(wftitle, wfauthor, wfsource, wffbtime, wflb, wfquate, wfdownl,
                                                   fillvalue=0):
                if w == 0:
                    df.append([k, v, m, n, q, b, w])
                else:
                    df.append([k, v, m, n, q, b, w])
            inf = pd.DataFrame(df)
            inf.to_csv('paper_wf_information.csv', mode='a', header=False, index=False, encoding='utf-8-sig')
            time.sleep(2)
    except:
        print('未爬到数据')
        time.sleep(2)

    
#----------爬取维普-------------------#
def start_cqvip_spider(aurname):  #爬取维普信息
    # 请求url
    cqvipurl = 'http://qikan.cqvip.com/Qikan/Search/Advance?from=index'
    browser.get(cqvipurl)
    # 显示等待输入框是否加载完成
    WebDriverWait(browser, 1000).until(
        EC.presence_of_all_elements_located(
            (By.CLASS_NAME, 'advance-submit')
        )
    )
    time.sleep(2)
    #设置第一查询条件,第一查询条件为单位名称
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div/div/div/div/input").click() #点击第一个检索条件下拉框
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div/div/div/dl/dd[@lay-value='S']").click() #选择检索条件为机构暨单位
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div/div/input").send_keys("清华大学")
    # 设置第二查询条件,第二查询条件为第一作者名称
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div[3]/div[2]/div/div/input").click() #点击第二个检索条件下拉框
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div[3]/div[2]/div/dl/dd[@lay-value='A']").click() #选择检索条件为作者
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div/div[3]/div/input").send_keys(aurname)
    browser.find_element_by_xpath("//div[@id='basic_searchdomainfilter']/div[@class='advance-submit']/button").click() #点击检索按钮
    time.sleep(3)  #检索后等待3秒,等待结果载入
    #如需更多查询条件可自行添加
    count=1
    name=[]
    try:
        divs = browser.find_elements_by_xpath(
            '//div[@id="tabDiv"]/div/div/div/div[@id="remark"]/dl'.format(2 * count - 1))
        i = 0
        for div in divs:  # 获取到文献标题信息
            namet = div.find_elements_by_xpath('//div[@id="tabDiv"]/div/div/div/div[@id="remark"]/dl/dt/a')
            name.append(namet[i].text)  # 获取文献名称
            i += 1

        authortt = div.find_elements_by_xpath('//div[@id="tabDiv"]/div/div/div/div[@class="simple-list"]/dl')
        t = 1
        authort = []  # 作者名字
        zazhititle = []  # 杂志名称
        zazhitime = []  # 出版时间
        for divaut in authortt:  # 获取对应文献作者信息
            aimulable = '//div[@id="tabDiv"]/div/div/div/div[@class="simple-list"]/dl[' + str(t) + ']/dd[3]/span/span'
            authortmp = div.find_elements_by_xpath(aimulable)
            aut = ""
            i = 0
            for audiv in authortmp:

                if audiv.text != '' and audiv.text != '作者':
                    if i == 0:
                        aut = audiv.text
                        i += 1
                    else:
                        aut = aut + ',' + audiv.text

            authort.append(aut)  # 作者姓名集合
            # -获取对应杂志名名称-#
            zzaimulable = '//div[@id="tabDiv"]/div/div/div/div[@class="simple-list"]/dl[' + str(t) + ']/dd[3]/span[2]/a'
            zztmp = div.find_element_by_xpath(zzaimulable)
            zazhititle.append(zztmp.text)
            # -----------------#
            # -获取对应杂志名名称-#
            zzaimtime = '//div[@id="tabDiv"]/div/div/div/div[@class="simple-list"]/dl[' + str(t) + ']/dd[3]/span[3]'
            zztimetmp = div.find_element_by_xpath(zzaimtime)
            zazhitime.append(zztimetmp.text)
            # -----------------#
            t += 1
            # 将查询到信息写入CSV文件#
            inf = pd.DataFrame(columns=['论文名', '作者', '来源', '发表日期'])
            inf.to_csv('paper_cqvipinformation.csv', index=False, encoding='utf-8-sig')
            df = []
            for k, v, m, n in zip_longest(name, authort, zazhititle, zazhitime, fillvalue=0):
                df.append([k, v, m, n])
            inf = pd.DataFrame(df)
            inf.to_csv('paper_cqvipinformation.csv', mode='a', header=False, index=False, encoding='utf-8-sig')
            time.sleep(2)
    except:
        print('未爬到数据')
        time.sleep(2)



def main():
    inf = pd.DataFrame(columns=['论文名', '作者', '来源', '发表日期', '数据库', '被引','下载次数'])
    inf.to_csv('paper_information.csv', index=False, encoding='utf-8-sig')
    authorsouce='dict.xls' #要检索的作者名字
    wb = xlrd.open_workbook(authorsouce)  # 打开Excel文件
    sheet = wb.sheet_by_name('Sheet3')  # 通过excel表格名称(rank)获取工作表
    for a in range(sheet.nrows):  # 循环读取表格内容(每次读取一行数据)
        cells = sheet.row_values(a)  # 每行数据赋值给cells
        aurname= cells[0]  # 因为表内可能存在多列数据,0代表第一列数据,1代表第二列,以此类推
        #start_spider(aurname)
        #start_wf_spider(aurname)  # 万方文献信息查询
        start_cqvip_spider(aurname) #维普文献信息查询
        print(aurname,'完成')

if __name__ == '__main__':
    main()