爬虫想必很多人都听过,这里简单介绍下爬虫,爬虫是一段可以在网页上自动抓取信息的程序,可以帮助我们获取一些有用的信息。能够完成上述功能的都可以称为爬虫,目前主流的Python爬虫框架主要分为调度器、URL管理器、网页下载器、网页解析器、应用程序(爬取的有价值数据)。调度器主要来调度管理器、下载器和解析器;URL管理器主要用来管理URL,防止重复抓取或者循环抓取等;网页下载器用于下载网页,并转换成字符串;网页解析器用于解析下载下来的字符串,目前主要以DOM树来解析,也可以根据XML,HTML进行解析。爬虫框架已经帮我们完成了80%的工作,我们只需要关注三个步骤:
1、如何能请求得到目标网站的数据,
2、如何从解析器中截取我们想要数据,
3、得到数据后如何做分析。
下面就以斗鱼网站上最火的直播主题,哪些主播的人气最高的目标为例,演示整个实现流程:
python环境搭建
python环境的搭建可以参考以下地址:http://www.runoob.com/python/python-install.html
爬虫框架还需要安装几个模块,requests和beautifulSoup4,分别运行命令,
pip install requests
pip install beautifulSoup4
开发工具选用PyCharm,运行完上面命令后,在PyCharm里安装上面两个组件模块,安装成功后,可以在开发工具里引入相关包
#!/usr/bin/python import requests from bs4 import BeautifulSoup as bs
如果引入成功,则安装完成。环境搭建完后,就开始码代码了。
获取目标网站信息
我们先打开斗鱼直播的网站,https://www.douyu.com/directory/all,F12可以看到网页的信息,
通过requests请求网站数据
response = requests.get("https://www.douyu.com/directory/all") print response.text
我们就得到了网页的字符串信息,这里就完成了我们关注的第一步。
解析网页信息
下面介绍如何在大量的文本中筛选出需要的数据,BeautifulSoup功能非常强大,通过DOM树的方式帮助我们解析出网页的结构,可以以Python自带的html.parser进行解析,也可以使用lxml进行解析。
html = response.text html_tree = bs(html, "html.parser") print html_tree 可以看到之前的字符串信息已经被格式化,得到很清晰的html文本。后面就可以很容易的获取DOM树中各个节点数据。我们可以观察到html文本中有用的数据都在<ul/>标签的<li/>中,房间名是<h3 class="ellipsis"/>标签的内容,房间类型在<span class="tag ellipsis"/>标签下,房间人数在<span class="dy-num fr"/>中,主播名在<span class="dy-name ellipsis fl"/>中。
在刚才解析出的html文本中,查找出id="live-list-contentbox"的<ul/>标签,并且获取所有的<li/>标签内容
# 查询ul标签 host_infos = html_tree.find("ul", {"id": "live-list-contentbox"}) # print host_infos # 查询所有li标签 host_list = host_infos.find_all("li") print host_list # 遍历获取直播信息 for host in host_list: #获取房间名 home_name = host.find("h3", {"class": "ellipsis"}).string.strip() home_name = home_name.replace(",", "") #获取主播名 p_str = host.find("p") host_name = p_str.find("span", {"class": "dy-name ellipsis fl"}).string.strip() #获取房间类型 home_type = host.find("span", {"class": "tag ellipsis"}).string #获取房间人数 home_num = host.find("span", {"class": "dy-num fr"}).string print "\033[31m房间名:\033[0m%s,\033[31m房间类型:\033[0m%s,\033[31m主播名称:\033[0m%s,\033[31m房间人数:\033[0m%s" \ % (home_name, home_type, host_name, home_num)
此时,我们就爬取到了数据分析需要的第1页数据,后面我们继续爬取2页,3页,。。。对于一般的网页来说,爬取数据的基本流程就这样。当然,不同网站爬取的难度不同,用到的技巧也会不一样,需要观察和思考怎样才能获取到有用数据。比如某些网站需要登录后才能获取数据,我们就需要模拟登录流程,保存cookie或者token用于请求数据。
就拿斗鱼网站来说,在我们点击翻页的时候,可以通过F12查看network请求,可以发现一个有意思的规律,
当我们点击第3页时,请求的链接是https://www.douyu.com/gapi/rkc/directory/0_0/3
点击第4页时,请求的链接是https://www.douyu.com/gapi/rkc/directory/0_0/4
请求链接末尾数字正好是请求的页码,因此,我们可以一次性获取几百页的数据,直接上代码,运行后就拿到了200页的直播信息数据。
#!/usr/bin/python # coding=UTF-8 import requests import json import sys # reload()之前必须要引入模块 reload(sys) sys.setdefaultencoding('utf-8') #解决中文乱码
count = 1 base_url = "https://www.douyu.com/gapi/rkc/directory/0_0/"
#存放数据路径 host_file_data = open("D:\\tmp_data\\file_data.csv", "w") host_file_data.write("房间名称,房间类别,主播名称,房间人数\n") #请求200页数据 while count < 200: request_url = base_url + str(count) response = requests.get(request_url) # load json data json_data = json.loads(response.text) for host_info in json_data["data"]["rl"]: # 解析json里面的房间名,房间类型,主播名称,房间人数 home_name = host_info["rn"].replace(" ", "").replace(",", "") home_type = host_info["c2name"] host_name = host_info["nn"] home_user_num = host_info["ol"] # print "\033[31m房间名:\033[0m%s,\033[31m房间类型:\033[0m%s,\033[31m主播名称:\033[0m%s,\033[31m房间人数:\033[0m%s"\ # % (home_name, home_type, host_name, home_user_num) #写入文件中 host_file_data.write(home_name + "," + home_type + "," + host_name + "," + str(home_user_num) + "\n") count += 1
数据的统计分析
我们的目标是统计目前最火的主题排名和最具人气的主播名称。python中的matplotlib库可以帮助我们快速的绘制2D图形,pandas库可以解决数据分析任务,这里用来完成导入和读取数据的任务。
可以通过pip install pandas和pip install matplotlib安装库,如果运行报SimHei not found,中文显示方框的问题:
首先将windwos中fonts目录下的simhei.ttf拷贝到Python根目录中的/python2.7/site-packages/matplotlib/mpl-data/fonts/ttf目录中,
然后删除~/.cache/matplotlib的缓冲目录,重新运行。
1.统计直播数最多的主题(房间类别)
import pandas as pd import matplotlib.pyplot as plt
df=pd.read_csv("/root/.jupyter/study_python/file_data.csv")#读取数据 #统计直播数最多的主题(房间类别) names=df["房间类别"].value_counts() plt.rcParams['figure.figsize']=(20.0,4.0)#设置图的尺寸 plt.rcParams['figure.dpi']=200 #设置分辨率 #设置图的字体 font={ 'family':'SimHei', 'weight':'bold', 'size':'15' } plt.rc('font',**font) plt.bar(names.index[0:15],names.values[0:15],fc='b') plt.show()
2.各个主题的直播观看人数排名
3.各个主播的观看人数排名
从数据爬取到数据分析,整个基本的流程就是这样,希望读者可以通过这个简单的示例能够对大数据和爬虫产生兴趣。后续将继续呈现上数据分析的进阶分享,谢谢。
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试