话不多说,我们先来安利一下本期文章演示视频
<iframe allowfullscreen="true" data-mediaembed="bilibili" id="T6E8DGTp-1625038238440" src="https://player.bilibili.com/player.html?aid=248930883"></iframe>写论文,这个工具爱了爱了
学习爬虫,我们可以做些什么?
这个问题从我开始开设《Python爬虫语法知识详解》就已经介绍的很清楚了,爬虫之所以可以作为我们学习Python语法的进阶项目,在于它的艺术美感和实用性。为什么我要说它的艺术美感呢,这个还是因人而异吧,毕竟每一个人心中都居住着另外一个自己,要善于发掘,而不是一味地追随。本期爬虫自动化项目,将带你走进科研的道路,博客专栏也开启了《Python爬虫实战系列》有兴趣的小伙伴,可以点击查看并学习。知识永无止境,学习仍需努力!
目录
项目背景
项目开展
数据挖掘
分析网页
Selenium语法详解
Webdriver模块的使用
解析网页
抓取数据
解析zip函数和zip_longest函数
存储数据
数据挖掘总结
数据分析
词云图
饼图绘制
代码资源下载(直接运行)
资源大放送!
每文一语
创作的灵感来源于生活!没有什么项目是空穴来风的,一切的实际操作都是为了解决我们的日常需要,毕竟这个社会是实用主义居多,我们要前进就需要学习,我比较喜欢CSDN上的一位博主,曾经说过这样一句话:我为了学习,需要不断的输入,当我学到了东西,就立马输出为自己的作品,这就是有效学习,我觉得非常有道理。
有人说爬虫写起来没有思路,没有框架,其实是没有真正的理解到爬虫的内涵,爬虫最重要的几步如下:
分析网页、解析网页、抓取数据、数据存储
导入第三方库
from selenium import webdriver import pandas as pd from itertools import zip_longest import time import random import os
本期我们要抓取的是知网页面的论文信息,相信大家在视频里面就已经看过了,第一步我们需要找到我的知网页面,我们知道知网反爬措施比较的严格,我们需要利用Python的自动化模块进行抓取,同时我们需要加入伪装头,需要延时请求页面,当然如果你要做比较大的项目更需要图像识别功能,绕开我们验证码阻碍。
在项目的演示视频中,我们首先需要输入我们的关键词,但是对于我们的浏览器,它是如何知道我们输入的文字呢?这个效果就需要借助我们Python第三方库:selenium
Selenium(浏览器自动化测试框架) 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
Selenium的配置
1、安装 Selenium模块: pip install Selenium
2、下载浏览器驱动,Selenium3.x调用浏览器必须有一个webdriver驱动文件
Chrome驱动文件下载:点击下载chromedrive
Firefox 驱动文件下载 :点解下载geckodriver
下载之后,解压到任意目录(路径不要有中文)!!!
Selenium的调用
from selenium import webdriver ## 如果是chrome浏览器的驱动 driver=webdriver.Chrome("C:\user\chromedriver.exe") ##如果是firefox浏览器的驱动 driver=webdriver.Firefox(executable_path="C:\user\geckodriver.exe") ######如果浏览器驱动的目录加入了环境变量的话 ## 如果是chrome浏览器的驱动 driver=webdriver.Chrome() ##如果是firefox浏览器的驱动 driver=webdriver.Firefox()
opt = webdriver.ChromeOptions() opt.add_experimental_option('excludeSwitches', ['enable-automation']) driver = webdriver.Chrome(options=opt) driver.get('https://www.cnki.net/old/') time.sleep(2)
add_experimental_option('excludeSwitches', ['enable-automation'])是开启开发者模式,可以有效的解决反爬的一些问题
如果看到这里,你可能比较懵,因为你不了解这个模块的语法和应用,下面详细的介绍一下
控制浏览器操作的一些方法
方法 | 说明 |
set_window_size() | 设置浏览器的大小 |
back() | 控制浏览器后退 |
forward() | 控制浏览器前进 |
refresh() | 刷新当前页面 |
clear() | 清除文本 |
send_keys (value) | 模拟按键输入 |
click() | 单击元素 |
submit() | 用于提交表单 |
get_attribute(name) | 获取元素属性值 |
is_displayed() | 设置该元素是否用户可见 |
size | 返回元素的尺寸 |
text | 获取元素的文本 |
鼠标事件
在 WebDriver 中, 将这些关于鼠标操作的方法封装在 ActionChains 类提供。
键盘事件
Selenium中的Key模块为我们提供了模拟键盘按键的方法,那就是send_keys()方法。它不仅可以模拟键盘输入,也可以模拟键盘的操作。
常用的键盘操作如下:
组合键的使用
获取断言信息
不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。通过我们获取title 、URL和text等信息进行断言。
我们可以通过Xpath或者beautifulsoup进行标签提取
driver.execute_script('window.scrollTo(0,document.body.scrollHeight)') paper_name = driver.find_elements_by_css_selector('a.fz14') author = driver.find_elements_by_css_selector('td.author_flag') source = driver.find_elements_by_css_selector('td.author_flag+td') datetime = driver.find_elements_by_css_selector('td.author_flag+td+td') database = driver.find_elements_by_css_selector('td.author_flag+td+td+td') download = driver.find_elements_by_css_selector('span.downloadCount')
定位元素的使用
说么这么多,其实你有可能还是比较的迷茫,下面我们通过一个具体的网页来了解一下
<html> <body> <form id="loginForm"> <input name="username" type="text" classname="xie" id="key"/> <input name="password" type="password" 型号 /> <input name="continue" type="submit" value="Login" /> <input name="continue" type="button" value="Clear" /> </form> <a href="http://www.baidu.com">百度一下</a> </body> </html>
通过id进行定位第一个input框: find_element_by_id("key")
通过name进行定位第一个input框:find_element_by_name("username")
通过classname进行定位第一个input框:find_element_by_class_name("xie")
通过标签tag进行定位input框:find_element_by_tag_name("input")
通过完整超链接定位a标签: find_element_by_link_text("百度一下")【推荐使用】
当然我们也可以用xpath进行定位
用绝对路径进行定位,input[1]代表form下面的第一个input标签,从1开始, input=input[1] driver.find_elemant_by_xpath("//html/body/form/input[1]") 用相对路径进行定位,form标签下的第一个input标签,[1]省略了 driver.find_element_by_xpath("//form/input") 用相对路径和属性进行定位,form标签下的input标签的name值等于username的标签 driver.find_element_by_xpath("//form/input[@name='username']") 其他的属性值如果太长,也可以采取模糊方法定位 例如页面中有这么一个标签 <a href="http://www.baidu.com?name=admin&passwd=pass&action=login">百度一下</a> 则可以这么使用 driver.find_element_by_xpath("//a[contains(@href,'login')]")
对于这个里面的语法,我们这里只是简单的了解一下,至于如何深入的去了解这个,还是要去官方的站点看看
for k, v, m, n, q, w in zip_longest(paper_name, author, source, datetime, database, download, fillvalue=0): if w == 0: df.append([k.text, v.text, m.text, n.text, q.text, w]) else: df.append([k.text, v.text, m.text, n.text, q.text, w.text]) # print(df) print('第{}页爬取完毕'.format(page)) driver.find_element_by_link_text('下一页').click() time.sleep(random.randint(2, 5))
这里我们的w是0,我们第一次就不会获取w的属性文本值,这样就可以极大的获取到我们有效数据,除此之外,我们使用列表存储,这里利用到Python的迭代库里面的语法。
然后自动化的找到“下一页”的这个标签,之后利用click点击,达到效果
学习就是在发现问题之后,要去学习,不然永远只会停留在我们的最初水平
zip:用来使列表一一对应,该函数返回一个以元组为元素的列表。返回的列表长度为最短列表的长度
letter = ['a', 'b', 'c', 'd'] dd = list(zip(letter)) print(dd) 输出结果: [('a',), ('b',), ('c',), ('d',)]
letter = ['a', 'b', 'c', 'd'] num = [1, 2, 3] dd = list(zip(letter, num)) print(dd) 输出结果: [('a', 1), ('b', 2), ('c', 3)]
letter = ['a', 'b', 'c', 'd'] num = [1, 2, 3] name = ['daicy', 'zhangsan'] dd = list(zip(letter, num, name)) print(dd) 输出结果: [('a', 1, 'daicy'), ('b', 2, 'zhangsan')]
zip_longest具体可以用来对列表的一一对应,如果列表的长度不一致,则其会选择最长的那个列表,并将没有的填充为None(这个可以自己传参时设置)
letter = ['a', 'b', 'c', 'd'] num = [1, 2, 3] name = ['daicy', 'zhangsan'] dic =[ll for ll in zip_longest(letter, num, name)] print(dic) 输出结果: [('a', 1, 'daicy'), ('b', 2, 'zhangsan'), ('c', 3, None), ('d', None, None)]
我们继续开始下一步的学习
inf = pd.DataFrame(data, columns=['论文名', '作者', '来源', '发表日期', '数据库', '下载次数']) # inf.to_csv('paper_information.csv',index=False,encoding='UTF-8') outputpath = ('E:\\个人文件\\Python\\Python源码\\基础项目\\知网科研\\{}.csv'.format(gjc)) #填写你要保存的路径 inf.to_csv(outputpath, sep=',', index=False, header=True, encoding='UTF-8')
这里比较的简单了,我们通过pands的方法dataframe对我们的数据进行存储到CSV文件里面,我们首先对标签进行的重述,然后有路径的描述,最后设置我们的编码,达到我们的存储效果。
数据挖掘到这里我们结束了,我们来理一下项目思路,首先我们回到知网爬取是比较的费工夫的,首先我们选择的是,自动化模块来解决,虽然在效率上有一点的不堪重任,但是对于我们初学者来说,还是比较的友好了,当然我们迫切需要数据的小白,也可以理解,最后我们利用里面的一些方法来模拟我们人工对浏览器发生的行为,这样可以极大的解决我们的反爬,达到我们的最终效果。
数据准备好了,这就结束了吗,可不是的,我们要从数据里面发掘有效地信息,最终用到我们的研究中去,这就需要我们有足够的的数据分析思维。
import pandas as pd # 导入pyecharts可视化库,词云渲染效果极佳 from pyecharts import options as opts from pyecharts.charts import WordCloud from pyecharts.globals import SymbolType import jieba # jieba用于分词,中文字典及其强大
这里我们选取我们jieba库,它是一个非常强大的中文分词库,此外我们用词云展示的是pyecharts这个库,这个库是我自己比较喜欢的可视化第三方库之一。因为强大,所以喜爱!
分词思路
我们首先知道我们分词的意义,我们的jieba只会把我们的词语分成我们的一些中文词组,有一些四字词语,三个字,两个字,一个字的,所以我自创了一种分词程序,适用多种场景的分词,我们可以根据我们的具体需要对其进行选择,部分代码如下:
a = ','.join(df['论文名'].to_list()) b = jieba.lcut(a) # 分词之后,把值储存到b这个变量 for x in b: # 遍历b这个,去除里面的特殊字符 if x in ",。、;:‘’“”【】《》?、.!…研究 大数据 基于 研究 分析 思考 展望 技术 应用 时代\n": continue else: # 分别分出有意义的词组,因为对于一个词的,分析没有太大的意义 if len(x) == 1: # 根据中文词组的特点,我们只需要得到2,3,4的词组即可,就可以达到分析目的 ll.append(x) # 存储1词组变量 elif len(x) == 2: lg.append(x) # 存储2词组变量 elif len(x) == 3: lk.append(x) # 存储3词组变量 elif len(x) == 4: lj.append(x) # 存储4词组变量
大数据一词组
大数据二词组
大数据三词组
大数据四词组
我们这里通过不同的功能按钮,选出不同的词云图
def plot_pie(df, groupby_name, groupby_sum_name, labels_name, fraces_name): df_group = df.groupby(groupby_name)[groupby_sum_name].sum().reset_index() labels = df_group[labels_name].to_list() fraces = df_group[fraces_name].to_list() colors = cm.rainbow(np.arange(len(labels))/len(labels)) explode = [] for i in range(len(labels)): explode = explode + [0.1] plt.axes(aspect=1) plt.pie(x=fraces, labels= labels, autopct='%1.1f%%', colors=colors, explode= explode, shadow=True) plt.show()
本期的文章到这里就结束了,喜欢的小伙伴欢迎评论区留言,赠送爬虫知识案例大礼包
留言格式:481255662@qq.com
懂得拒绝,适度自私,才是最智慧的表现