美文网首页blastn本地库构建
Python爬虫技术实例详解及数据可视化库

Python爬虫技术实例详解及数据可视化库

作者: 过过的算法笔记 | 来源:发表于2023-04-06 21:26 被阅读0次

    前言

    在当前数据爆发的时代,数据分析行业势头强劲,越来越多的人涉足数据分析领域。面对大量数据,人工获取信息的成本高、耗时长、效率低,那么是否能用代码去完成大量复杂的工作,从而从网络上获取到目标信息?由此,网络爬虫技术应运而生。

    本文目录,你将会看到

    • 网络爬虫简介
    • 实例分析
    • 示例背景
    • 问题总括
    • 示例全代码
    • 数据处理与可视化之Altair
    • 后言-python爬虫相关库

    网络爬虫简介

    网络爬虫(webcrawler,又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种用来自动浏览万维网的程序或者脚本。爬虫可以验证超链接和HTML代码,用于网络抓取(Webscraping)。传统爬虫从一个或若干初始网页URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。爬虫访问网站的过程会消耗目标系统资源,因此在访问大量页面时,爬虫需要考虑到规划、负载等问题。

    实例分析

    示例背景

    1. 利物浦足球俱乐部(Liverpool F.C.),简称利物浦,球队位于英格兰西北默西赛德郡港口城市利物浦,于1892年成立,是英格兰足球超级联赛的球队之一。2018/19赛季,利物浦2比0战胜热刺,历史上第六次捧起欧洲冠军联赛冠军奖杯。
    2. 目标网站:T足球(http://tzuqiu.cc/

    问题总括

    1. 为研究利物浦球队在欧冠中的整体表现,现需从T足球网站中获取利物浦在18/19赛季欧冠中的所有比赛的比赛报告,其中包括:数据类型分析、总计、球队进攻分布、球队数据以及TOP球员数据,并将其结果存储为本地文件,以便后续数据分析工作。


      在这里插入图片描述
    2. 操作思路:首先查看该网站的robohttp://tzuqiu.cc/matches/56141/report.dots协议(Robots Exclusion Protocol),获取目标网址、请求访问、获取源码文本、选择目标信息、存储文件。
    3. 问题分析:该网站上没有18/19赛季比赛的专栏,提前通过度娘,检索到共有13场比赛(6场积分赛、7场淘汰赛)比赛时间,获取网址需要自行选择比赛时间后才能查看到当场比赛网址。其中C组积分赛事情况见下表。
    时间 赛况 网址
    2018年9月18日 利物浦 3:2 巴黎圣日耳曼 http://tzuqiu.cc/matches/56141/report.do
    2018年10月3日 那不勒斯 1:0 利物浦 http://tzuqiu.cc/matches/56138/report.do
    2018年10月24日 利物浦 4:0 贝尔格莱德红星 http://tzuqiu.cc/matches/56139/report.do
    2018年11月6日 贝尔格莱德红星 2:0 利物浦 http://tzuqiu.cc/matches/56147/report.do
    2018年11月28日 巴黎圣日耳曼 2:1 利物浦 http://tzuqiu.cc/matches/56144/report.do
    2018年12月11日 利物浦 1:0 那不勒斯 http://tzuqiu.cc/matches/56146/report.do
    • 在目标网址中仅有“数字码”不一致,猜测剩下7场比赛网址(url)结构一致。同理,获取到剩下7场淘汰赛的“数字码”,将13个“数字码“放在一个列表中,并构造链接”
    urls = [56141,56138,56139,56147,56144,56146,56933,56931,57970,57967,58344,58341,58471]
    for url_0 in urls:
        url = "http://tzuqiu.cc/matches/" + str(url_0) + "/report.do"
        print(url)
    
    • 接下来需要先请求访问网站,获取源码文本数据,首先利用requests库进行请求,再获取文本。python的第三方库requests库安装方法:本地搜索:cmd (命令提示符),键入代码后等待下载安装(Tip:对于python中大多数第三方库都可以通过程序命令符pip程序进行下载、安装、删除等)。
    pip install requests
    
    • 由于爬虫代码是在短时间内多次访问目标网站,会对目标网站造成资源浪费,网站可能会建立有反爬虫机制,在请求访问网站时,目标网站会对申请访问对象进行身份识别。因此,需要先将爬虫代码伪装为一个浏览器,构造“请求头”,即:
    heads = {
         'Connection': 'keep-alive',
        'Accept-Language': 'zh-CN,zh;q=0.9',
         'Accept': 'text/html,application/xhtml+xml,application/xml;\
         q=0.9,image/webp,image/apng,*/*;q=0.8',
         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36\
        (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',}
        
    
    • 申请访问后,若目标网站回应“Response [200]”则表示成功,若为Response [404]或者其他则可以粗略理解为失败。
    import requests
    url = "http://tzuqiu.cc/matches/56141/report.do"
    response = requests.get(url, headers = heads)
    print(response)
    #返回结果:Response [200]
    
    • 成功访问后,获取源码,以便分析,可以打印浏览,也可以忽略打印,在网页中直接分析
    content = response.text
    
    • 打开目标网站-鼠标右键-检查/查看网页源代码,观察目标信息位置以及规律特征


      在这里插入图片描述
    • 发现“数据类型分析”的“射门”与“传球”信息都存储在一个“div”标签 属性满足唯一字典,标签下的文本无其他干扰信息,同理可发现另外三个板块的字典信息。
    类型 div标签下特征字典
    数据类型分析 {"class":"tabbable smallTab"}
    总计 {"class":"team-stats team-stats-table"}
    球队进攻分布 {"class":"col-xs-4 team-stats team-stats-compare"}
    球队数据、TOP球员数据 {"class":"col-xs-4 side-bar"}
    • 可利用BeautifulSoup库中find_all()函数查找目标信息,由于观察到该网页一个的特殊字典唯一,所以也可以用find()方法,查找到目标信息后,提取div标签下的所有文本信息。(BeautifulSoup库的安装-在cmd环境下键入:pip install bs4)
    string = ["tabbable smallTab","team-stats team-stats-table",
                  "col-xs-4 team-stats team-stats-compare","col-xs-4 side-bar"]
    s_sum = []
    for reast in string:
            tagss = soup.find_all('div',attrs = {"class":reast})
            for tags in tagss:
            print(tags.text)
    
    • 对数据进行格式清洗,去掉所有的空格、转行,并以逗号分隔添加到列表
    for tags in tagss:
        s_old = re.sub(r"\s+",",",tags.text)
        s_new = s_old.strip(",''")
        s_sum.append(s_new)
        s_sum_new = str(s_sum).replace("'","") 
    
    • 到此已经爬取完网页上的所有目标信息,接下来将数据存储为txt文本
    f = open(r"存储路径\py_txt文本_sum.txt",'w')
    f.writelines([s_sum_new,'\n'])
    f.close()
    
    • txt文本以逗号为制表符转换成excel文件。也可以直接将爬取的数据以excel文件存储【Python实现的HTML/XML处理库,仅需少量代码,效率相对较低】但不清楚爬取的数据内部结构,可能会导致excel表格式杂乱无章,故用txt文本更为简便。
    import xlwt
    import os 
    import sys
    def txt_xls(filename,xlsname):
        try:
            f = open(filename)
            xls = xlwt.Workbook()
          
            sheet = xls.add_sheet('sheet',cell_overwrite_ok=True)
            x = 0   
            while True:     
                line = f.readline()     
                if not line:  
                    break
                for i in range(len(line.split(','))):   
                    item = line.split(',')[i]
                    sheet.write(x,i,item)     
                x += 1 
            f.close()
            xls.save(xlsname)        
        except:
            raise
    if __name__ == '__main__':
        filename = 'txt文本存储本地路径.txt'
        xlsname = 'excel存储地址.xlsx'
        txt_xls(filename,xlsname)
    
    • excel表格转换成csv文件,虽然csv打开方式与xlsx一样,但文件属性各异。
    import xlwt
    import pandas as pd
    file = '文件路径/py_excel表格_sum.xlsx'
    outfile = '文件路径/py_csv文件_sum.csv'
    def xlsx_to_csv_pd():
        data_xls = pd.read_excel(file, index_col=0)
        data_xls.to_csv(outfile, encoding='utf-8')
    if __name__ == '__main__':
        xlsx_to_csv_pd()
    
    • 优化爬虫:在爬取过程中,经常会遇到“无限循环”“爬取结果为空”等情况,并不知道爬虫进展如何,则可以通过简单的语言实现爬虫进度。例如:
    for i in range(len(urls)):
        print("正在爬取第%d个网站"%i)
    
    • 利用time库的时间戳,记录程序运行耗时
    import time
    star_time = time.time()
    ##爬虫代码
    end_time = time.time()
    spend_time = end_time - star_time
    print(spend_time)
    
    • 则整个爬虫过程进度可视化


      在这里插入图片描述

    示例全代码

    import requests
    import re
    from bs4 import BeautifulSoup
    import time
    import xlwt
    import os 
    import sys
    import pandas as pd
    print("爬虫计时开始...")
    star_time = time.time()
    heads = {
         'Connection': 'keep-alive',
        'Accept-Language': 'zh-CN,zh;q=0.9',
         'Accept': 'text/html,application/xhtml+xml,application/xml;\
         q=0.9,image/webp,image/apng,*/*;q=0.8',
         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36\
        (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',}
    urls = [56141,56138,56139,56147,56144,56146,56933,56931,57970,57967,58344,58341,58471]
    f = open(r"D:\Users\py_txt文本_sum.txt",'w')
    m = 1
    for url_0 in urls:
        print("已成功爬取第%d场比赛"%m)
        m += 1
        url = "http://tzuqiu.cc/matches/" + str(url_0) + "/report.do"
        response = requests.get(url, headers = heads)
        content = response.text
        soup = BeautifulSoup(content,"lxml")
        string = ["tabbable smallTab","team-stats team-stats-table",
                  "col-xs-4 team-stats team-stats-compare","col-xs-4 side-bar"]
        for reast in string:
            s_sum = []
            tagss = soup.find_all('div',attrs = {"class":reast})
            for tags in tagss:
                s_old = re.sub(r"\s+",",",tags.text)
                s_new = s_old.strip(",''")
                s_sum.append(s_new)
            s_sum_new = str(s_sum).replace("'","")   
            f.writelines([s_sum_new,'\n'])    
    f.close()
    def txt_xls(filename,xlsname):
        try:
            f = open(filename)
            xls = xlwt.Workbook() 
            sheet = xls.add_sheet('sheet',cell_overwrite_ok=True)
            x = 0   
            while True:    
                line = f.readline()    
                if not line:    
                    break
                for i in range(len(line.split(','))):  
                    item = line.split(',')[i]
                    sheet.write(x,i,item)      
                x += 1 
            f.close()
            xls.save(xlsname)       
        except:
            raise  
    if __name__ == '__main__':
        filename = 'D:/Users/soccer_sum/py_txt文本_sum.txt' 
        xlsname = 'D:/Users/py_excel表格_sum.xlsx'
        txt_xls(filename,xlsname)
    file = 'D:/Users/py_excel表格_sum.xlsx'
    outfile = 'D:/Users/py_csv文件_sum.csv'
    def xlsx_to_csv_pd():
        data_xls = pd.read_excel(file, index_col=0)
        data_xls.to_csv(outfile, encoding='utf-8')
    if __name__ == '__main__':
        xlsx_to_csv_pd()
    end_time = time.time()
    time = end_time - star_time
    print("爬虫结束,TXT文本、excel表格、csv文件保存成功")
    print("计时结束,共耗时:%d秒"%time)
    
    
    • 最终爬取结果


      在这里插入图片描述

    数据处理与可视化之Altair

    Altair是一个专为Python编写的可视化软件包,它能让数据科学家更多地关注数据本身和其内在的联系。
    
    • 绘制图表
    chart = alt.Chart(cars)
    
    • Chart有三个基本方法:数据(data)、标记(mark)和编码(encode)
    alt.Chart(data).mark_point().encode(
    encoding_1='column_1',
    encoding_2='column_2',
    # etc.
    )
    
    • 进一步了解编码具体内容
    变量 名称
    x x轴数值
    y y轴数值
    color 标记点颜色
    size 标记点的大小
    opacity 标记点的透明度
    row 按行分列图片
    column 按列分列图片

    绘制二维图

    alt.Chart(cars).mark_line().encode(
    x='Miles_per_Gallon',
    y='Horsepower'
    )
    
    在这里插入图片描述
    • 交互图形,在选择功能上,我们能做出一些更酷炫的高级功能,例如对选中的数据点进行统计,生成实时的直方图。


      在这里插入图片描述
    • 在统计学上,我们还能定义平均值的置信区间,为了让图表更好看,可以分别列出三个不同的平均值置信区间
    alt.Chart(cars).mark_area(opacity=0.3).encode(
    x=alt.X(‘Year’, timeUnit=’year’),
    y=alt.Y(‘ci0(Miles_per_Gallon)’, axis=alt.Axis(title=’Miles per Gallon’)),
    y2=’ci1(Miles_per_Gallon)’,
    color=’Origin’
    ).properties(
    width=600
    )
    
    在这里插入图片描述

    后言-python爬虫相关库

    在这里插入图片描述
    • python网络爬虫技术相关库
    库名 简介
    urllib Python内置的httpP请求库,提供一系列用于操作url的功能
    Requests 基于urllib,采用Apache2 Licensed开源协议的HTTP库
    urllib 提供多种python所没有的重要特性:线程安全,连接池,客户端SSL/TLS验证等
    scrapy 一个为了爬取网站数据,提取结构性数据而编写的应用框架
    lxml C语言编写高效HTML/XML处理库,支持XPath
    BeautifulSoup 纯Python实现的HTML/XML处理库,仅需少量代码,效率相对较低

    END:创作不易,点个关注呗~


    相关文章

      网友评论

        本文标题:Python爬虫技术实例详解及数据可视化库

        本文链接:https://www.haomeiwen.com/subject/rbmeddtx.html