简述
本次实训的项目为知识图谱的构建,本阶段的个人工作为数据的爬取,本次爬取的网站为知网空间(https://search.cnki.com.cn/)使用的方法为selenium模拟浏览器操作的方式
一、准备工作
确保自己的电脑上安装有浏览器,并安装对应的webdrive(webdriver的版本号要与浏览器保持对应)本次使用的是chrome浏览器(版本 89.0.4389.114(正式版本) (64 位)),以及对应版本号的chromeDriver
(注:如果此处电脑上只有chromium内核的浏览器,例如新版edge,爬虫可能会启动不了,可以去下载对应的edgedriver_win64,将代码中的chromedriver路径替换即可)
二、数据爬取
1.chromeDriver设置
代码如下(示例):
import time
from selenium import webdriver
import warnings
path = r'D:\software\chromedriver_win32\chromedriver.exe'
#chromedriver.exe文件存放的绝对路径
chrome_options = webdriver.ChromeOptions()
prefs = {
'profile.default_content_setting_values': {
'images': 2,
#'permissions.default.stylesheet':2,
#增加设置爬取中不加载图片和css,在编写时可以先不隐藏css,
#便于查找问题
}
}
chrome_options.add_experimental_option('prefs', prefs)
#爬取单个关键词
def confSet(content):
url = "https://search.cnki.com.cn/Search/Result?content="
url = url + content
return url
2.页面元素定位
通过F12开发者工具定位页面元素
首先确定要爬取数据的位置,可以看到每一篇文章信息都可以从“lplist”属性中遍历"list-item"得到
获取文章具体信息的方式有两种
(1)需要的信息在标签内部
文章的名称和下载链接通过class=left定位,然后通过get_attribute()函数获取href和title属性的内容。
代码如下(示例):
# 文章名称
title = article.find_element_by_class_name("left").get_attribute("title")
# 下载地址
url = article.find_element_by_class_name("left").get_attribute("href")
(2)需要的信息在text中
此时只要定位到具体的标签并提取text即可,也可以通过xpath的方式获得
代码如下(示例):
# 发表时间
paper_date = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-2].text
3.页面翻页
定位翻页元素,模拟点击,但是由于知网空间翻页没有直接跳转,所以只能通过一页一页点击后翻页
# bottom_page = driver.find_element_by_class_name("page").find_element_by_tag_name(
# "strong").find_element_by_class_name("pc").text
#
# print('page_no', page_no, 'bottom_page', bottom_page)
# if bottom_page == str(page_no):
# a = driver.find_element_by_class_name("page").find_elements_by_class_name("n")[1]
# print(a.text)
# a.click()
a = driver.find_element_by_class_name("page").find_elements_by_class_name("n")[1]
print(page_no)
a.click()
time.sleep(2)
4.一些小细节
通过class=source可以定位到文章的信息,其中包括作者,发表来源,发表时间,文章类型,通过类似第二步中对source中的span标签遍历可以得到所需信息
在运行爬虫爬取10页信息后,通过分析数据得到部分数据字段出现了问题,这是由于文献中有一种类型为硕士论文和博士论文,在这些文献中会包含有导师信息,会导致如果按顺序遍历的话存储时会出现问题,因此修改遍历顺序,对属性位置的定位进行小的修改
# 作者
author = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[0].get_attribute("title")
# 期刊来源
source = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-3].get_attribute("title")
# 发表时间
paper_date = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-2].text
# 类型
srcDatabase = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-1].text
总结
使用方法
link = confSet('机器学习')
#修改关键词
driver.get(link)#不用修改
crawl_page(1, 40)#爬取页数
save('./testData.csv')#存储路径
小结
对爬取的内容可以使用一个列表存储,通过for循环遍历实现自动化爬取,将csv存储时也可以将等待list存储一定量的数据后再打开csv将其写入,这样可以避免list中数据量过多使得内存溢出,也避免了多次打开文件导致的io时间损耗
附代码
import time
from selenium import webdriver
import warnings
import re
import pandas as pd
import csv
warnings.filterwarnings("ignore")
path = r'D:\software\chromedriver_win32\chromedriver.exe'
# chromedriver.exe文件存放的绝对路径
chrome_options = webdriver.ChromeOptions()
prefs = {
'profile.default_content_setting_values': {
'images': 2,
# 'permissions.default.stylesheet':2,
# 增加设置爬取中不加载图片和css,在编写时可以先不隐藏css,
# 便于查找问题
}
}
chrome_options.add_experimental_option('prefs', prefs)
name = ['srcDatabase', 'title', 'author', 'source', 'keyword', 'download', 'quote', 'paperDate', 'url']
lists = []
path = r'D:\software\chromedriver_win32\chromedriver.exe'
driver = webdriver.Chrome(executable_path=path, options=chrome_options)
def confSet(content):
url = "https://search.cnki.com.cn/Search/Result?content="
url = url + content
return url
def crawl():
for article in driver.find_element_by_class_name("lplist").find_elements_by_class_name("list-item"):
try:
# 下载量
download = article.find_element_by_class_name("time1").text
download = re.findall(r'\d+', download)[-1]
# 引用量
quote = article.find_element_by_class_name("time2").text
quote = re.findall(r'\d+', quote)[-1]
# 文章名称
title = article.find_element_by_class_name("left").get_attribute("title")
# 下载地址
url = article.find_element_by_class_name("left").get_attribute("href")
# 作者
author = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[0].get_attribute(
"title")
# 期刊来源
source = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-3].get_attribute(
"title")
# 发表时间
paper_date = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-2].text
# 类型
srcDatabase = article.find_element_by_class_name("source").find_elements_by_tag_name("span")[-1].text
keyword = article.find_element_by_class_name("info").find_elements_by_tag_name("a")[0].get_attribute(
"data-key")
lists.append([srcDatabase, title, author, source, keyword, download, quote, paper_date, url])
except Exception as err:
print('', err)
else:
pass
def save(save_path):
test = pd.DataFrame(columns=name, data=lists)
test.to_csv(save_path, encoding='utf-8-sig')
def crawl_page(start, end):
for page_no in range(start, end):
crawl()
# bottom_page = driver.find_element_by_class_name("page").find_element_by_tag_name(
# "strong").find_element_by_class_name("pc").text
#
# print('page_no', page_no, 'bottom_page', bottom_page)
# if bottom_page == str(page_no):
# a = driver.find_element_by_class_name("page").find_elements_by_class_name("n")[1]
# print(a.text)
# a.click()
a = driver.find_element_by_class_name("page").find_elements_by_class_name("n")[1]
print(page_no)
a.click()
time.sleep(2)
driver.quit()
link = confSet('机器学习')
driver.get(link)
crawl_page(1, 40)
save('./testData.csv')