本篇文章主要记录了调用python的urllib、bs4、re(正则表达式)等库爬取《自动化学报》的数据的过程和代码。以及针对数据进行词云分析,调用matplotlib库绘制相应的数据分析图。
注:文章提供的代码分为网络爬虫和数据分析两个部分。网络爬虫部分爬取了论文作者和关键词两个数据,安装好相应库之后,可以直接运行,并将数据保存至excel中。数据分析部分只提供了词云分析的代码。
你可以从这篇文章看到网络爬虫和词云分析的基本使用,如果有疑问,可以一起交流。
代码一:只有网络爬虫的内容,爬取《自动化学报》的论文作者数据,保存至excel中。
注:代码已经经过验证,可以直接运行。如果不能运行,很有可能是网络的问题或者是代理的问题。因为没有网络就无法爬虫。(大部分代码可以断网直接执行,但爬虫需要网络)
import urllib.request,urllib.error
from bs4 import BeautifulSoup
import re
import pandas as pd
findlink2=re.compile(r'authorNameCn.,.\t?(.*?)..;.>') #正则表达式定义 论文作者
def askURL(url,a): #获取网页源代码
if a==1:
head={"User-Agent": "Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"}
else:
head={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}
request=urllib.request.Request(url,headers=head) #head:代理信息 获取url网站的源代码
try:
request=urllib.request.urlopen(request) #打开
html=request.read().decode("utf-8") #解码
# print(html)
except:
print("error")
return html #返回源代码
def main(): #主函数
base_url2='http://www.aas.net.cn/article/latest_all' #《自动化学报》网
#获取网页源代码
html=askURL(base_url2,1)
# print(html) #测试爬取的源代码
soup=BeautifulSoup(html,"html.parser") #解码成html
# print(soup) #测试爬取的源代码
# print(type(html),type(soup))
temp1=0
temp3=0 #爬取每个论文的具体网站
data_web=[] #论文的具体网站
data_keyword=[] #论文关键字
all_auther=[]
##################################爬取论文作者 解析数据
for item in soup.find_all('div', class_='article-list-author'):
item = str(item)
link2 = re.findall(findlink2, item)
link2 = ','.join(link2) # 将列表转化为字符串
all_auther.append(link2)
temp1 += 1
if temp1 >= 200:
break
print(all_auther)
#保存数据
f = pd.DataFrame(data=all_auther).to_excel('论文作者《自动化学报》.xlsx', encoding='utf-8')
if __name__ == "__main__":
main()
代码二:包含了网络爬虫和词云分析两个部分,爬取了《自动化学报》前200篇论文的关键词,并对关键字做了词云分析。
注:因为词云分析需要mask掩膜和字体文件。所以要下载这两个文件才能直接运行代码。
百度网盘链接(包含了mask掩膜图片和字体文件):
https://pan.baidu.com/s/1kJo1DQW0eis-G3MwYk5RHw
提取码:
x9jq
import urllib.request,urllib.error
from bs4 import BeautifulSoup
import re
import pandas as pd
import numpy as np
from wordcloud import WordCloud
import matplotlib.pylab as plb
findlink3=re.compile(r'keywordCn.,.(.*?)..">') #论文关键字
findlink4=re.compile(r'href="(.*?)"') #论文具体网站
def askURL(url,a): #获取网页源代码
if a==1:
head={"User-Agent": "Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"}
else:
head={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}
request=urllib.request.Request(url,headers=head) #head:代理信息 获取url网站的源代码
try:
request=urllib.request.urlopen(request) #打开
html=request.read().decode("utf-8") #解码
# print(html)
except:
print("error")
return html #返回源代码
#词云分析需要的函数,处理mask掩膜
def transform_format(val):
# pixel transformation
if val >= 1:
return 255
else:
return 0
def main(): #主函数
base_url2='http://www.aas.net.cn/article/latest_all' #《自动化学报》网
#获取网页源代码
html=askURL(base_url2,1)
soup=BeautifulSoup(html,"html.parser") #解码成html
# print(soup) #测试爬取的源代码
temp3=0 #爬取每个论文的具体网站
data_web=[] #论文的具体网站
data_keyword=[] #论文关键字
#####################################################################################爬取关键词
##(1)一次爬虫:爬取具体网站。
for item in soup.find_all('div', class_='article-list-title'):
item = str(item)
# print(item)
link4 = re.findall(findlink4, item)
data_web.append(link4[0]) # 保存字符串,而不是列表
# print(link4)
temp3 += 1
if temp3 >= 100: # 爬取网站的个数为150
break
#print(data_web) #网站信息保存至data_web中
##(2)二次爬虫:爬取论文关键词
for i, web in enumerate(data_web):
html = askURL(web, 1)
# print(html)
soup = BeautifulSoup(html, "html.parser")
for item in soup.find_all('ul', class_='article-keyword'):
item = str(item)
# print(item)
link5 = re.findall(findlink3, item)
print(link5)
for i, j in enumerate(link5): # 将爬取的数据,放在同一个列表中
if j != '':
data_keyword.append(j) # 保存为列表形式,每个元素都是一个关键字
break # 只处理第一个,第二个为英文版关键字
#print(data_keyword)
######################################################################################爬虫结束
############################################################词云分析
##统计频率次数
wordDict = {} # 字典
wordSet = set(data_keyword) # 用于生成不重复元素集合,先记录关键词
for w in wordSet:
if len(w) > 1:
wordDict[w] = data_keyword.count(w) # 确定关键词词频
## 排序
wordList = list(wordDict.items())
wordList.sort(key=lambda x: x[1], reverse=True) # 把结果存放到文件里
##保存为csv文件
former_five = pd.DataFrame(data=wordList).to_excel('词频.xlsx', encoding='utf-8')
##取前40个名单,制作词云
df = pd.read_excel('词频.xlsx', index_col=None)
former_five = df.values[0:40, 1]
s = " ".join(i for i in former_five)
x = np.array(plb.imread('big_thinker.png'))
x = x[:, :, 1]
transformed_x = np.ndarray((x.shape[0], x.shape[1]))
transformed_x = np.array([list(map(transform_format, x[i])) for i in range(len(x))])
wordcloud = WordCloud(font_path='STKAITI.TTF', background_color='white',
mask=transformed_x, contour_color='firebrick', contour_width=30).generate(s)
wordcloud.to_file(r'词云7.jpg')
################################################################################################词云分析结束
if __name__ == "__main__":
main()
安装爬虫需要的相应库,包括:urllib、bs4、re、xlwt、pandas、numpy等等。
确定爬取的网站是《自动化学报》,网址为:
http://www.aas.net.cn/article/latest_all
获取数据的主要工作就是获取网页的源代码,主要步骤分为:调用urllib库获取网页源代码,按utf-8格式解码源代码,调用bs4将源代码转化为bs4类型。
获取源代码:urllib的request函数,模拟浏览器向网页申请源代码。源代码保存至request变量中。
需要注意的是:在获取网页的时候,我们设置了head(代理)变量,是模仿浏览器向网页发送我们电脑的相关信息,借此来获得网页的源代码(通过申请)。要强调的有两点,一是动态网页才需要代理,静态网页不需要,而这里是静态网页其实是不需要代理。二是每个人的代理信息是不同的,要想确定自己的代理信息是什么,可以借用浏览器,打开开发者模式,在相应的位置查看。
按utf-8格式解码源代码:获取的源代码还是乱码,要转为utf-8的格式。
def askURL(url,a): #获取网页源代码
if a==1:
head={"User-Agent": "Mozilla/5.0(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"}
else:
head={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"}
request=urllib.request.Request(url,headers=head) #head:代理信息 获取url网站的源代码
try:
request=urllib.request.urlopen(request) #打开
html=request.read().decode("utf-8") #解码
# print(html)
except:
print("error")
return html #返回源代码
调用bs4将源代码转化为bs4类型:在后面的步骤中,我们使用了bs4库来解析数据。要将源代码数据类型转化为bs4,才能调用bs4库。经过下面这一步后,网页源代码的类型,就从字符串转化为了bs4类型,便于bs4库调用。
html=askURL(base_url2,1)
# print(html) #测试爬取的源代码
soup=BeautifulSoup(html,"html.parser") #解码成html
解析数据实际上就是针对获取的源代码,通过bs4库和正则表达式等方法将网页中我们所需要的信息提取出来。
先调用bs4库,缩小正则提取的范围。利用浏览器的开发者模式,定位到论文作者的源代码这栏。其html源代码对应为:div和article-list-author。
调用bs4库的find_all函数将这部分提取出来。
for item in soup.find_all('div', class_='article-list-author'):
写相应的正则表达式精准提取信息,即做最后的信息筛选。下面的正则表达式中(.*?)这部分即为要提取的信息。
link2 = re.findall(findlink2, item)
调用re库(正则表达式)做精准信息提取。要注意的是,bs4库处理的对象是bs4数据类型,而re库处理的是str,也即是Python自带的字符串类型。
保存数据:爬虫的最后一步,即将数据保存到excel中。这里是保存到excel中,当然也能够保存至csv和txt等等。
调用pandas的to_excel函数,将刚才以列表形式存储的论文作者数据保存至excel文件中。
f = pd.DataFrame(data=all_auther).to_excel('论文作者《自动化学报》.xlsx', encoding='utf-8')