Python:基于爬虫技术的数据分析

爬取的网站:CSDN中我的个人主页

网址:https://blog.csdn.net/Faith_cxz(可根据自己需要找寻对应网址)

目的:获取到该主页的基本信息,包括文章标题、发表时间、访问量、排名等信息

全部代码可通过此gitee账号来获取:蔡欣致 (zkcxz) - Gitee.comhttps://gitee.com/zkcxz

本次爬取数据的代码链接(有两个):

实例题or项目/爬虫项目/课程设计-爬虫技术和词云图.py · 蔡欣致/Python练习 - Gitee.com

实例题or项目/爬虫项目/课程设计-绘制柱状图与折线图.py · 蔡欣致/Python练习 - Gitee.com

本次需要导入模块(也就是Python库)有以下几个,可提前安装:

import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
import jieba
from wordcloud import WordCloud
import pandas
import matplotlib
import matplotlib.pyplot as plt

第一步,我们在getHTMLText( )函数中先伪装成浏览器访问,不然爬取CSDN会爬不到数据;然后就是发送请求,获取首页内容。具体代码如下(已规范好,可直接套用):

def getHTMLText(url):
    user_agent = 'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)'
    headers = {'User-Agent': user_agent}
    response = requests.get(url, headers=headers)
    home_page = response.content.decode()
    # print(response.text)
    return home_page

第二步,我们要使用BeautifulSoup提取首页数据,具体代码如下(已规范好,可直接套用):

def getSoup(url):
    txt = getHTMLText(url)
    soup = BeautifulSoup(txt, 'html.parser')
    return soup

第三步,分为两个内容:

第一,爬取左栏博主基本信息。博主基本信息包括:名字、原创篇数、周排名、总排名、总访问量、等级,因为原创篇数、周排名、总排名、总访问量、等级在相同的标签下,有相同的class,所以,可以直接使用遍历来获取所需的数据,然后定义一个列表,最后将这些数据存入列表中,具体代码见下:

def getContent2(soup):
    contents2 = soup.find('div', {'class': 'aside-box'})
    global all_word
    articles2 = []

    name = contents2.find('span', {'class': 'name'})
    name = name.string
    str2 = name + ','
    articles2.append([name])
    item = contents2.find('div', {'class': 'data-info d-flex item-tiling'})
    date = 0
    for date in item.find_all('dl'):
        date = date['title']
        str2 += date + ',' 
        articles2.append([date])

第二,爬取右栏文章基本信息。文章基本信息包括:文章发表时间、访问次数、标题、创作类型,这里同样会发现文章发表时间、访问次数、标题、创作类型也都在相同的标签下,有相同的class,所以,也可以直接使用遍历来获取所需的数据,然后同样定义一个列表,将这些数据存入列表中,具体代码见下:

def getContent1(soup):
    contents1 = soup.find('div', {'class': 'article-list'})
    global all_word
    articles1 = []
    for item in tqdm(contents1.find_all('div', {'class': 'article-item-box csdn-tracking-statistics'}), '采集博主所有文章中'):
        date = item.find('span', {'class': 'date'})
        date = date.text
        watch = item.find('span', {'class': 'read-num'})
        watch = watch.text
        title = item.find('p', {'class': 'content'})
        title = title.string
        article_type = item.find('span', {'class': 'article-type type-1 float-none'})
        article_type = article_type.string
        str1 = title + ',' + article_type + ',' + watch + ',' + date + '\n'
        file.write(str1.encode('gbk', 'ignore').decode('gbk', 'ignore'))
        all_word = all_word + title + article_type + watch + date + ' '
        articles1.append([title, article_type, watch, date])

这里,第二部分内容相比第一部分多了一些东西,比如用tqpm对遍历进行操作,进而能够查看爬取数据的进度,使运行时能够更加清晰地看到爬取进度;此外,我们还会发现,我们会用专门的一个函数来对'gdk’格式进行忽略,避免因为一些数据格式的不同导致运行的错误。

第四步,创建一个CSV文件来存储这些数据,分别将左栏和右栏的内容传进CSV文件中,并注明表头标题,具体代码见下:

file = open('D:\\Python文件\\blogger-data-last.csv', 'w')

# 左栏内容制成表格导入CSV文件中
str2 = '博主昵称,原创篇数,周排名,总排名,总访问量,等级\n'
file.write(str2)
soup = getSoup(url)
getContent2(soup)

# 右栏内容制成表格导入CSV文件中
str1 = '\n文章标题,文章创作类型,访问次数,发表时间\n'
file.write(str1)
soup = getSoup(url)
getContent1(soup)

以上的四个步骤,就可以将该网站上所需的数据爬取下来到CSV中。接下来,就是对爬取出来的这些数据绘制成几个图表,也称为可视化处理。

图一,词云图。计算词出现的频率,若该词出现次数越多,则会在窗口上显示的就越大且越靠中间;否则,会在窗口上显示在角落旁且字体非常小。那么,如何制出一张合格的词云图呢?我们可以先定义一个全局变量,然后将想要计算词频的数据全部存进这个全局变量中,再将这个变量中的所有词用jieba库将其切割开,最后用wordcould库来将这些切割开的数据绘制成一张图(记得改用中文字体),就可以很直观地看出哪些词出现的多,哪些词出现的少了,具体代码见下:

# 将搜集到的词用jieba库分隔开
word_cut = jieba.lcut(all_word)
word_cut = " ".join(word_cut)

# 读取数据,绘制成词云图
word_cloud = WordCloud(font_path="simsun.ttc")
word_cloud = word_cloud.generate(word_cut)
plt.plot(figsize=(15, 10))
plt.imshow(word_cloud)
plt.axis("off")
plt.show()

运行后得出的结果如下图:

 

图二,柱状图。首先,我们要确定纵坐标和横坐标,就比如这里,我想研究其每月发表的文章数量,所以,把月份作为横坐标,把该月发表文章数量作为纵坐标。接下来,我们的思路就是,先用pandas库来获取发布时间列的数据,再将其中的月份用下标索引抽取出来,整理爬取到的数据中每个月份分别出现多少次,这里,就可以用之前计算词出现次数的那个方法来计算,这里就不展开详细讨论了,然后将他们存入列表中,就可以很好的把图作出来了。具体代码见下:

lst1 = []
df = pandas.read_csv("D:\\Python文件\\blogger-data-alreadylast.csv", encoding="ANSI")
for i in range(len(df)):
    if str(df.iat[i, 3][5:7]) == '10' or str(df.iat[i, 3][5:7]) == '11' or str(df.iat[i, 3][5:7]) == '12':
        date = int(df.iat[i, 3][5:7])
    else:
        date = int(df.iat[i, 3][5:6])
    lst1.append(date)
lst1.sort()
set1 = set(lst1)
lst2 = list(set1)
map1 = {}
for num in lst1:
    if num in map1:
        map1[num] += 1
    else:
        map1[num] = 1
map1 = map1.values() 
lst3 = list(map1)
plt.figure(figsize=(8, 6))
y1 = lst3
x = lst2
plt.bar(x, y1, color="blue", width=0.5)
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
plt.xlabel("月份")
plt.ylabel("每月发表文章数量")
plt.show()

运行后得出的结果如下图:

图三,折线图。首先,同样的,我们要确定纵坐标和横坐标,就比如这里,我想研究每月的访问数量,所以,把月份作为横坐标,把该月访问量作为纵坐标。接下来,我们的思路就是,先用pandas库来获取访问次数列的数据将,再将该月的每篇文章的访问量加起来,每个月都循环这样,然后,将他们存入列表中,就可以很好的把图作出来,具体的代码见下:

df = pandas.read_csv("D:\\Python文件\\blogger-data-alreadylast.csv", encoding="ANSI")
y2 = df.访问次数
lst4 = list(y2)
lst4.reverse()
lst5 = []
for i in range(len(lst3)):
    sum = 0
    for j in range(lst3[i]):
        sum += lst4[j]
    del lst4[0:lst3[i]]
    lst5.append(sum)

matplotlib.rcParams['font.sans-serif'] = ['SimHei'] 
plt.plot(lst2, lst5, "r", marker='.', ms=10, label="a")
plt.xlabel("月份")
plt.ylabel("该月总访问量")
plt.legend(loc="upper left")
for x1, y1 in zip(lst2, lst5):
    plt.text(x1, y1 + 1, str(y1), ha='center', va='bottom', fontsize=20, rotation=0)
plt.show()

运行后得出的结果如下图:

到此,就能很好的把整个项目运行出来,这样就可以根据自己的需要更换网址来按自己的想法爬取数据,其中,上述的代码中也有很多是模板的,也可以根据自己需要进行套用等。

到这里,想要本项目完整代码的,可以回到开头说的那个gitee网址就可以获取到 。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔡欣致

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值