Python零基础速成班-第12讲-Python获取网络数据Socket,API接口,网络爬虫Crawler(制作弹幕词云)

学习目标

  1. 获取网络数据Socket
  2. API接口
  3. 网络爬虫Crawler(制作弹幕词云)
  4. 课后作业(2必做)

友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。

1、Python获取网络数据

了解通过Python完成Socket通信的简单实例。

Socket定义:

  • Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
  • Socket 是对 TCP/IP 协议族的一种封装,是应用层与TCP/IP协议族通信的中间软件抽象层。
  • Socket把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

Socket获取网络数据的四个步骤:

  1. 创建Socket
  2. 连接服务器
  3. 发送数据
  4. 关闭连接

1.1 创建Socket

socket.socket函数的前两个参数的默认值是socket.AF_INET和socket.SOCK_STREAM,创建TCP socket时可以直接写成socket.socket()。

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

1.2 连接服务器

以下三种都是合法的,注意没有前缀http或https

s.connect(('localhost', 8000))
s.connect(('127.0.0.1', 8000))
s.connect(('www.baidu.com', 80))

1.3 发送数据

发送数据有两个方法send和sendall

  • send() 发送TCP数据,返回发送的字节大小。这个字节长度可能少于实际要发送的数据的长度。换句话说,这个函数执行一次,并不一定能发送完给定的数据,可能需要重复多次才能发送完成。
data = "something you want to send"
while True: len = s.send(data[len:]) if not len: break

sendall() 发送完整的TCP数据,成功返回None,失败抛出异常

data = "something you want to send"
s.sendall(data)

1.4 关闭连接

当连接不再需要时可以使用close关闭socket连接,关闭后的连接不能再进行任何操作。

s.close()

1.5 完整代码示例:获取百度网首页的数据

进阶提示:urllib库parse模块的urlparse可以帮我们实现URL地址各部分的抽取、合并以及链接转换。
如 https://www.baidu.com/s?wd=百度热搜
url.netloc转化为路径-> www.baidu.com
url.path转化为地址-> s?wd=百度热搜

import socket
from urllib.parse import urlparse
def get_url(url):url = urlparse(url)host = url.netlocpath = url.pathif path == "":path = "/"#创建socket连接并发送请求数据client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect((host, 80))client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf-8"))#返回数据,设置为Byte格式,采用分步接收response = b""while True:data = client.recv(4096) #分步接收,每次4096字节if data:response += dataelse:break            response = response.decode("utf-8")#返回数组第一项为响应文本,第二项为响应内容即网页内容html_data = response.split("\r\n\r\n")[1]print(html_data)#关闭连接client.close()
#获取百度网首页的数据
if __name__ == '__main__':get_url("https://www.baidu.com")

2、API接口

在实际应用中,我们推荐使用Requests包来获取网络数据,包括API接口和爬虫。

Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。

  1. 首先我们需要安装Requests包:pip install requests

  2. 大部分response.text返回的是Unicode格式,通常需要转换为utf-8格式,否则就是乱码。这时我们可以通过以下两种方式转码:

    1. 直接将内容转码:response.content.decode(“utf-8”)
    2. 设置编码格式后再输出内容:response.encoding = “utf-8” 再执行response.text
  3. 请求方式包括多种,GET请求、POST请求、PUT请求、DELETE请求等,可以理解为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,增,改,删4个操作。

请求类型 请求类型的说明文档
GET请求 GET请求用来查询数据,不会修改、增加数据,不会影响资源内容。
POST请求 POST请求一般是对服务器的数据做改变,常用于数据的提交、新增操作。
PUT请求 PUT请求的侧重点在于对于数据的修改操作。
DELETE请求 DELETE请求一般用来删除某一个资源的。

2.1 通过实例学习Requests使用

例1,我们使用requests包来获取百度首页的数据,仅需三行代码,这里我们发送的是GET请求。

import requests
response = requests.get(url="https://www.baidu.com")
response.content.decode("utf-8")
'<!DOCTYPE html>\r\n<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write(\'<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=\'+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ \'" name="tj_login" class="lb">登录</a>\');\r\n                </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>\r\n'

例2,我们通过post把数据提交到url地址,等同于以字典的形式提交form表单里面的数据。

进阶提示:
请求头中(http请求中的header部分)的编码方式content-type一般包括:

  1. application/x-www-form-urlencoded,当请求为GET时候,浏览器用该方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串加到url后面,用?分割,加载这个新的url。如:https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1
  2. multipart/form-data,当请求为POST时候,浏览器把form数据封装到http body中,然后发送到服务器,一般适用于文件传输。
  3. text/plain,以纯文本形式进行编码,其中不含任何控件或格式字符。
  4. application/json,一般用于POST请求,将json数据封装到http body中,然后发送到服务器,适用于数据交互。
import requests
url = 'http://httpbin.org/post'
mydata = {'name':'Jack','age':'28'}
myheaders = {"Content-Type":"application/json;charset=UTF-8"}
response = requests.post(url,data=mydata,headers=myheaders)
print(response.content.decode("utf-8"))
{"args": {}, "data": "name=Jack&age=28", "files": {}, "form": {}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Content-Length": "16", "Content-Type": "application/json;charset=UTF-8", "Host": "httpbin.org", "User-Agent": "python-requests/2.26.0", "X-Amzn-Trace-Id": "Root=1-629827a5-57a465dd45bdeef31a0951bc"}, "json": null, "origin": "61.139.91.108", "url": "http://httpbin.org/post"
}

例3,文件上传,我们在D盘根目录创建一个test.txt,将其上传至服务器。

文件会转为Byte格式,通过Base64编码后,放入files字段中进行传输。

import requests
url = "http://httpbin.org/post"
files= {"files":open("D://test.txt","rb")}
response = requests.post(url,files=files)
print(response.content.decode("utf-8"))
{"args": {}, "data": "", "files": {"files": "data:application/octet-stream;base64,MjAyMi0wNS0zMSAxMToxNTo0NSwzMjIgLSAgV0FSTklORyAtICBFcnJvcjogw7vT0NXStb3OxLz+u/K2wcihzsS8/sqnsNwNCg=="}, "form": {}, "headers": {"Accept": "*/*", "Accept-Encoding": "gzip, deflate, br", "Content-Length": "218", "Content-Type": "multipart/form-data; boundary=e3e837dec7b537789994f8e32e739be0", "Host": "httpbin.org", "User-Agent": "python-requests/2.26.0", "X-Amzn-Trace-Id": "Root=1-62982b13-1dd468c06ce969d056a88985"}, "json": null, "origin": "61.139.91.108", "url": "http://httpbin.org/post"
}

例4,超时设置,通过timeout参数可以设置超时的时间,并通过requests.exceptions抛出报错。

设置必须在100ms内收到响应,不然或抛出ReadTimeout异常。

import requests
from requests.exceptions import ReadTimeout
try:response = requests.get("http://httpbin.org/get", timeout=0.1)print(response.status_code)
except Exception as ex:print("请求超时,文本为:",repr(ex))
请求超时,文本为: ConnectTimeout(MaxRetryError("HTTPConnectionPool(host='httpbin.org', port=80): Max retries exceeded with url: /get (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x000002040231F970>, 'Connection to httpbin.org timed out. (connect timeout=0.1)'))"))

例5,获取cookie,会话session维持

Cookie 能够保存有关访问者的信息。更概括地说,Cookie 是一种保持 Web 应用程序连续性的方法。因此 Cookie 的作用就类似于名片,它提供了相关的标识信息,可以帮助应用程序确定如何继续执行。例如一些要求用户登录的站点则可以通过 Cookie 来确定您是否已经登录过,这样您就不必每次都输入账号密码。

cookie和session区别:

  1. cookie数据存放在客户的浏览器上,session数据放在服务器上。
  2. cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗。
  3. session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。
  4. 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
import requests
response = requests.get('https://www.baidu.com')
print(response.cookies)
for key,value in response.cookies.items():print(key,'==',value)
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
BDORZ == 27315

cookie的一个作用就是可以用于模拟登陆,做会话维持。如下例,我们给服务器上的会话设置cookie,接下来获取会话的cookie。

import requests
session = requests.session()
session.get('http://httpbin.org/cookies/set/number/654321')
response = session.get('http://httpbin.org/cookies')
print(response.text)
{"cookies": {"number": "654321"}
}

2.2 通过API接口获取数据

API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。

例1,不带任何参数的API接口,历史上的今天API接口,请求类型GET

import requests
response = requests.get("http://api.wpbom.com/api/today.php")
print(response.text)
1:1992年06月07日 -戏剧家阳翰笙逝世
2:1970年06月07日 -英国作家爱德华·福斯特去世
3:1956年06月07日 -举重运动员陈镜开第一次打破世界纪录
4:1951年06月07日 -敦煌文物研究所受嘉奖
5:1915年06月07日 -中俄蒙签订协约
6:1902年06月07日 -山西设立大学堂
注意:由内容过长,只显示10个列

例2,带参数的API接口,新华字典查字,参数msg为要查的汉字

import requests
r = requests.get(url="http://api.wpbom.com/api/search.php?msg=接")
r.encoding="utf-8"
print(r.text)
查询:接
音节:jie</span>
部首:扌
部首笔画:3
部外笔画:8
总数笔画:11
笔顺写法:12141431531

例3,返回JSON格式的API接口,随机输出毒鸡汤

我们通过JSON包来处理JSON格式的数据

import requests
import json
r = requests.get("http://api.btstu.cn/yan/api.php?charset=utf-8&encode=json")
r.content.decode("utf-8")
print("API状态码:",r.status_code)
print(r.text)
joke = json.loads(r.text)
print(joke["text"])
API状态码: 200
{"text":"钱买不到快乐是假的,你那点钱买不到快乐是真的。"}
钱买不到快乐是假的,你那点钱买不到快乐是真的。

例4,返回JSON格式(多值)的API接口,查询域名示范已被注册,参数domain为要查询的域名

我们通过pprint包来格式化打印JSON格式的结果,width=10表示超过10个字节即按照pprint定义的格式打印

import requests
import pprint
r = requests.get("http://api.btstu.cn/dmreg/api.php?domain=www.baidu.com")
r.content.decode("utf-8")
result = json.loads(r.text)
pprint.pprint(result,width=10)
{'code': '202','domain': 'www.baidu.com','msg': '域名已被注册'}

2.3 通过API接口获取天气预报小型项目开发实例

2.3.1 项目目标:实现某个城市近三天天气预报:日出日落、月升月落、最高最低温度、天气白天和夜间状况、风力、风速、风向、相对湿度、大气压强、降水量、降水概率、露点温度、紫外线强度、能见度等。(本次项目只取最高气温、最低气温、天气概览、湿度四个字段)

2.3.2 前期准备:

1. 天气预报服务商:和风天气 https://www.qweather.com
2. API接口文档:https://dev.qweather.com/docs/api/weather
3. API接口开发KEY申请:需要注册登录并申请免费的开发KEY https://id.qweather.com
4. 项目所需要的Package包:① Requests包,用来调用API接口② JSON包,用来处理JSON格式数据③ Pandas包,用来快速处理数据

2.3.3 程序第一步:首先获取天气预报的城市的id(我们以都江堰市为例),Key为我自己申请的开发Key,后期建议自行申请。

城市API接口为 https://geoapi.qweather.com/v2/city/lookup
传入参数location为城市中文或英文名字
传入参数key为我们申请的开发KEY

import json
import numpy as np
import pandas as pd
import requests
key = "3746c837ff16452b90b5ef2c7533b758"#这里是我们申请的开发KEY,后期建议自行申请
city = requests.get("https://geoapi.qweather.com/v2/city/lookup?location={}&key={}".format("都江堰",key))
print(city.text)
#获取id
cityjson = json.loads(reponse.text)
print("城市id是:",cityjson["location"][0]["id"])
{"code":"200","location":[{"name":"都江堰","id":"101270111","lat":"30.99114","lon":"103.62789","adm2":"成都","adm1":"四川省","country":"中国","tz":"Asia/Shanghai","utcOffset":"+08:00","isDst":"0","type":"city","rank":"33","fxLink":"http://hfx.link/3tu1"}],"refer":{"sources":["QWeather"],"license":["commercial license"]}}
城市id是: 101270111

2.3.4 程序第二步:获取都江堰市最近三天天气预报数据。

近三天天气预报接口为 "https://devapi.qweather.com/v7/weather/3d
传入参数location为城市id
传入参数key为我们申请的开发KEY

wether = requests.get("https://devapi.qweather.com/v7/weather/3d?location={}&key={}".format("101270111",key))
weatherjson = json.loads(wether.text)
print(weatherjson)
{'code': '200', 'updateTime': '2022-06-06T12:35+08:00', 'fxLink': 'http://hfx.link/3tu1', 'daily': [{'fxDate': '2022-06-06', 'sunrise': '06:02', 'sunset': '20:07', 'moonrise': '11:37', 'moonset': '01:17', 'moonPhase': '峨眉月', 'moonPhaseIcon': '801', 'tempMax': '29', 'tempMin': '19', 'iconDay': '104', 'textDay': '阴', 'iconNight': '104', 'textNight': '阴', 'wind360Day': '0', 'windDirDay': '北风', 'windScaleDay': '1-2', 'windSpeedDay': '3', 'wind360Night': '0', 'windDirNight': '北风', 'windScaleNight': '1-2', 'windSpeedNight': '3', 'humidity': '64', 'precip': '0.0', 'pressure': '890', 'vis': '25', 'cloud': '25', 'uvIndex': '11'}, {'fxDate': '2022-06-07', 'sunrise': '06:02', 'sunset': '20:07', 'moonrise': '12:34', 'moonset': '01:47', 'moonPhase': '上弦月', 'moonPhaseIcon': '802', 'tempMax': '29', 'tempMin': '18', 'iconDay': '300', 'textDay': '阵雨', 'iconNight': '350', 'textNight': '阵雨', 'wind360Day': '0', 'windDirDay': '北风', 'windScaleDay': '1-2', 'windSpeedDay': '3', 'wind360Night': '0', 'windDirNight': '北风', 'windScaleNight': '1-2', 'windSpeedNight': '3', 'humidity': '69', 'precip': '1.0', 'pressure': '890', 'vis': '23', 'cloud': '60', 'uvIndex': '8'}, {'fxDate': '2022-06-08', 'sunrise': '06:02', 'sunset': '20:07', 'moonrise': '13:33', 'moonset': '02:16', 'moonPhase': '盈凸月', 'moonPhaseIcon': '803', 'tempMax': '26', 'tempMin': '17', 'iconDay': '300', 'textDay': '阵雨', 'iconNight': '350', 'textNight': '阵雨', 'wind360Day': '0', 'windDirDay': '北风', 'windScaleDay': '1-2', 'windSpeedDay': '3', 'wind360Night': '0', 'windDirNight': '北风', 'windScaleNight': '1-2', 'windSpeedNight': '3', 'humidity': '81', 'precip': '1.0', 'pressure': '889', 'vis': '16', 'cloud': '55', 'uvIndex': '4'}], 'refer': {'sources': ['QWeather', 'NMC', 'ECMWF'], 'license': ['no commercial use']}}

获取第一天的天气

print("最低气温:",weatherjson['daily'][0]['tempMin'])
print("最高气温:",weatherjson['daily'][0]['tempMax'])
print("天气情况:",weatherjson.get('daily')[0].get('textDay'))
print("湿度:",weatherjson.get('daily')[0].get('humidity'))
最低气温: 19
最高气温: 29
天气情况: 阴
湿度: 64

2.3.5 程序第三步: 整理数据,形成以下数据结构,并通过Pandas展示。

{
"tempMin":[day1,day2,day3]
"tempMax":[day1,day2,day3]
"textDay":[day1,day2,day3]
"humidity":[day1,day2,day3]
}
needs = ["tempMin","tempMax","textDay","humidity"]#需要取值的字段
weatherdict={need:[] for need in needs}#初始化数据结构{'tempMin': [], 'tempMax': [], 'textDay': [], 'humidity': []}
for daily in weatherjson["daily"]:#循环近三天天气for need in needs:#将需要取值的字段添加到对应数组中weatherdict[need].append(daily[need])
weatherdict
{'tempMin': ['19', '18', '17'],'tempMax': ['29', '29', '26'],'textDay': ['阴', '阵雨', '阵雨'],'humidity': ['64', '69', '81']}

Pandas展示

index=[i for i in range(1,4)]
index
[1, 2, 3]
w =pd.DataFrame(weatherdict,index=["第一天","第二天","第三天"])
w
tempMin tempMax textDay humidity
第一天 19 29 64
第二天 18 29 阵雨 69
第三天 17 26 阵雨 81

3、网络爬虫Crawler(制作弹幕词云)

网络爬虫又称网络蜘蛛、网络蚂蚁、网络机器人等,可以自动化浏览网络中的信息,当然浏览信息的时候需要按照我们制定的规则进行,这些规则我们称之为网络爬虫算法。使用Python可以很方便地编写出爬虫程序,进行互联网信息的自动化检索。

3.1 通过网络爬虫制作弹幕词云小型项目开发实例

3.1.1 项目目标:通过网络爬虫获取某站番剧弹幕,进行数据整理、分词、生成弹幕词云。

3.1.2 前期准备:(网址中的毕里毕里请大家自行替换)

1. 网络爬虫获取弹幕网页地址: 番剧鲁邦三世 https://www.毕里毕里.com/bangumi/play/ss39468
2. 项目所需要的Package包:① Requests包,用来爬取网页数据② bs4.BeautifulSoup包,HTML/XML解析器,用来处理网页数据③ jieba包,用来分词④ wordcloud包,用来生成词云⑤ matplotlib.pyplot包,用来展示弹幕词云
3.上述包如果不包含在Anacoda3中,则需要通过"pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名"进行安装。(重要)① pip install -i https://pypi.tuna.tsinghua.edu.cn/simple BeautifulSoup② pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba③ pip install -i https://pypi.tuna.tsinghua.edu.cn/simple wordcloud  #手动安装地址https://www.lfd.uci.edu/~gohlke/pythonlibs/#wordcloud

3.1.3 程序第一步:获取弹幕网址并进行爬取。

获取弹幕网址操作顺序如下:

  1. 首先点进一个视频网页如https://www.毕里毕里.com/bangumi/play/ss39468 ,点击F12,进入Network获取监测页面,然后一定要点击播放视频,我们选择Fetch/XHR,在资源过滤Filter中输入cid,然后任意点击一个进入即可。
  2. cid就是该剧弹幕的id号,这个id是唯一的,获取弹幕网址固定xml格式是:https://comment.毕里毕里.com/视频的cid.xml 。
  3. 以番剧鲁邦三世为例,我们最终获取到弹幕的网址是:https://comment.毕里毕里.com/430717173.xml 。

接下来,根据弹幕网址,爬取弹幕数据。

import requests
crawler = requests.get("https://comment.毕里毕里.com/430717173.xml")
crawler.encoding='utf-8'
crawler.text

3.1.3 程序第二步:数据整理、分词。

  1. 我们发现爬取下来的弹幕XML均有规律,即都是以标签"d"开头,所以我们只需用Beautifulsuop来选取所有标签为"d"的就可以。
  2. 我们将d标签数据转化为弹幕数组list格式。
  3. 数据清洗:统一英文大小写,去掉空格,去掉重复及一些不必要的字符等。
  4. 分词并去掉单字节的内容。
from bs4 import BeautifulSoup #HTML/XML解析器,处理网页数据
import jieba #分词
soup = BeautifulSoup(crawler.text,"lxml")
results = soup.find_all("d")#找出所有"d"
comments = [comment.text for comment in results]#转化为弹幕list,注意,b站弹幕提取上线是1000条,大于则会随机选取1000条
comments = [comment.upper() for comment in comments]#统一英文大小写
comments = [comment.replace(' ','') for comment in comments]#去掉空格
comments = [comment for comment in set(comments) if comment not in ["!!","??",",。"]]#去掉重复及一些不必要的字符
danmu = ''.join(comment for comment in comments)#合成一个字符串
ciyun = list(jieba.cut(danmu))#分词
ciyun = [word for word in ciyun if len(word)>1]#去掉单字节的内容
ciyun[0:10]#因为数据量大,我们取前十个
['回忆', '可能', '别说', '什么', '绝对', '没死', '哈德森', '太太', '我姐', '区区']

3.1.4 程序第三步:生成弹幕词云并展示。

import wordcloud #生成词云
from matplotlib import pyplot as plt #展示弹幕词云
wc = wordcloud.WordCloud(width=1000, font_path='simfang.ttf',height=800)#设定词云画的大小字体,一定要设定字体,否则中文显示不出来
wc.generate(' '.join(ciyun)) #合成一个字符串后放入词云画布中
plt.imshow(wc) #展示词云
<matplotlib.image.AxesImage at 0x2aee43b8a30>

3.2 接下来将上述程序打包为一个函数,再生成神探狄仁杰2的弹幕词云

我们先补充一下wordcloud包,词云图片输出的常用参数有:

  • width 词云图片宽度,默认400像素
  • height 词云图片高度 默认200像素
  • background_color 词云图片的背景颜色,默认为黑色background_color=‘white’
  • font_step 字号增大的步进间隔 默认1号
  • font_path 指定字体路径 默认None,对于中文可用font_path=‘msyh.ttc’
  • mini_font_size 最小字号 默认4号
  • max_font_size 最大字号 根据高度自动调节
  • max_words 最大词数 默认200
  • stop_words 不显示的单词 stop_words={“python”,“java”}
  • scale 默认值1。值越大,图像密度越大越清晰
  • prefer_horizontal:默认值0.90,浮点数类型。表示在水平如果不合适,就旋转为垂直方向
  • relative_scaling:默认值0.5,浮点型。设定按词频倒序排列,上一个词相对下一位词的大小倍数。有如下取值:“0”表示大小标准只参考频率排名,“1”如果词频是2倍,大小也是2倍
  • mask 指定词云形状图片,默认为矩形
import requests
from bs4 import BeautifulSoup
import jieba
import wordcloud
from matplotlib import pyplot as plt
def danmu(url:"弹幕XML地址")->"输出弹幕云":#爬取弹幕数据crawler = requests.get(url)crawler.encoding='utf-8'#数据整理、分词soup = BeautifulSoup(crawler.text,"lxml")results = soup.find_all("d")comments = [comment.text for comment in results]comments = [comment.upper() for comment in comments]comments = [comment.replace(' ','') for comment in comments]comments = [comment for comment in set(comments) if comment not in ["!!","??",",。"]]danmu = ''.join(comment for comment in comments)ciyun = list(jieba.cut(danmu))ciyun = [word for word in ciyun if len(word)>1]#生成弹幕词云并展示,font_path指定字体路径,scale指定图像清晰度,数值越大越清晰,程序耗时越久wc = wordcloud.WordCloud(width=1200, font_path='simfang.ttf',height=800,scale=5)wc.generate(' '.join(ciyun))plt.imshow(wc)
danmu("https://comment.毕里毕里.com/483236581.xml")#神探狄仁杰2

4、课后作业,答案在下一讲

1、编程实践项目:利用百度智能云API服务制作一个手机号码归属地查询API接口。

  1. 目标要求:输入手机号,查询手机号码归属地信息、包含省市区、运营商、区号等信息。
  2. API服务地址:https://apis.baidu.com/store/detail/51d4c4fa-002e-4592-853c-2aaedf39d457
  3. 提示:
    1. 第一步:注册登录百度智能云,点击API服务地址申请购买一个10000次免费手机号码归属查询的Key(AppCode),用Python代码调用该API接口,获取手机号码归属地等数据。
    2. 第二步:将返回的数据转化为JSON格式,依次输出运行商、省份、城市、区号、邮编等信息。

参考代码如下:

import requests
url = 'https://hcapi02.api.bdymkt.com/mobile'
params = {}
params['mobile'] = ''
headers = {        'Content-Type': 'application/json;charset=UTF-8','X-Bce-Signature': 'AppCode/您的AppCode'
}
r = requests.request("GET", url, params=params, headers=headers)
print(r.content)
您的代码:

2、编程实践项目:利用网络爬虫,爬取文件信息,生成文件的词云图片。

  1. 目标要求:从 http://www.gov.cn/zhengce/2021-02/21/content_5588098.htm 中获取《关于全面推进乡村振兴加快农业农村现代化的意见》网页源码,进行数据整理、分词、生成词云图片并展示。
  2. 提示:
    1. 爬取文件网页源码,转化为utf-8格式。
    2. 寻找文件规律,使用BeautifulSoup查询转化,输出数组,文件信息是以段落标签"p"开头的,不需要去除空格和重复。
    3. 分词,去掉单字符和内容为"\r\n"的单词。
    4. 生成词云图片并展示(图片长度1200,高度800,清晰度3,背景底色白色,字体"msyh.ttc")。
    5. 需要使用requests、BeautifulSoup、jieba、wordcloud、matplotlib包,需要自行安装。
您的代码:

5、上一讲Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life 课后作业及答案

1、写一个计算程序,计算一个list列表[3,5,0,4.5,0.8,7,14]的第i项元素与第j项元素相除的结果,使用try/catch,对可能遇到除数为0,i,j超出数组界限等错误进行输出。不断完善你的程序,使其可以正常执行不报错。i,j通过input()输入。

list = [3,5,0,4.5,0.8,7,14]
try:i=int(input("请输入第i项:\n"))j=int(input("请输入第j项:\n"))if j ==0:raise ZeroDivisionError("除数不能为0")if i > len(list) or j > len(list):raise IndexError("输入超出数组范围")print(list[i]/list[j])
except Exception as ex:print("异常:"+repr(ex))
请输入第i项:
3
请输入第j项:
2
异常:ZeroDivisionError('float division by zero')

2、设计一个函数,统计并输出0至n相加之和,n由input输入。在函数执行前输出INFO日志(“日期时间—日志级别—统计0至n相加之和程序开始!”)当n > 100万时,输出ERROR日志(“日期时间—日志级别—n大于100万!”),仅输出日志不影响程序。

import logging
logging.basicConfig(level=logging.INFO,encoding='utf-8',format='%(asctime)s -  %(levelname)s -  %(message)s')
def sums(n):logging.info("统计0至%s相加之和程序开始!" %n)if n >1000000:logging.error("%s大于100万!" %n)total = 0for i in range(n+1):total+=ireturn total
n = int(input("请输入n的值\n:"))
print(sums(n))
请输入n的值
:10000012022-06-07 14:41:14,306 -  INFO -  统计0至1000001相加之和程序开始!
2022-06-07 14:41:14,307 -  ERROR -  1000001大于100万!500001500001

Python零基础速成班-第12讲-Python获取网络数据Socket,API接口,网络爬虫Crawler(制作弹幕词云)相关推荐

  1. Python零基础速成班-第13讲-Python正则表达式Regex

    Python零基础速成班-第13讲-Python正则表达式Regex 学习目标 正则表达式 课后作业(4必做) 友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连 ...

  2. Python零基础速成班-第9讲-Python面向对象编程(上),对象和类、初始化、继承、重写、多态、类方法、组合

    Python零基础速成班-第9讲-Python面向对象编程(上),对象和类.初始化.继承.重写.多态.类方法.组合 学习目标 修饰器 面向对象编程:对象和类.初始化.继承.重写.多态.类方法.组合 课 ...

  3. Python零基础速成班-第10讲-Python面向对象编程(下),Property属性、特殊方法、设计模式、链表应用

    Python零基础速成班-第10讲-Python面向对象编程(下),Property属性.特殊方法.设计模式.链表应用 学习目标 面向对象编程 接上一讲:Property属性.特殊方法.设计模式 面向 ...

  4. Python零基础速成班-第5讲-Python函数,Function和Lambda基础

    Python零基础速成班-第5讲-Python函数,Function和Lambda基础 学习目标 Function函数 Lambda Function函数 课后作业(4必做) 友情提示:将下文中代码拷 ...

  5. Python零基础速成班-第6讲-Python异常处理Exception,tryexcept,raise,assert,输入模块pyinputplus

    Python零基础速成班-第6讲-Python异常处理Exception,try&except,raise,assert,输入模块pyinputplus 学习目标 异常处理Exception: ...

  6. Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life

    Python零基础速成班-第11讲-Python日志Logging,小游戏设计game of life 学习目标 Python日志Logging 小游戏设计game of life 课后作业(2必做) ...

  7. Python零基础速成班-第8讲-Python文件操作File IO、高级文件处理模块shutil、CSV、JSON、多线程基础

    Python零基础速成班-第8讲-Python文件操作File I&O.高级文件处理模块shutil.CSV.JSON.多线程基础 学习目标 文件操作File I/O 高级文件处理模块shut ...

  8. Python零基础速成班-第14讲-Python处理Excel和Word,使用openpyxl和docx包详解,图表入门

    Python零基础速成班-第14讲-Python处理Excel和Word,使用openpyxl和docx包详解,图表入门 学习目标 Python处理Excel(使用openpyxl包).图表入门\ P ...

  9. Python零基础速成班-第2讲-Python基础(上),运算、变量、数据类型、输入输出

    Python零基础速成班-第2讲-Python基础(上),运算.变量.数据类型.输入输出 学习目标 使用print输出结果 运算及运算符 变量 数据类型(4种最常用的) 输入输出 课后作业(4必做+1 ...

最新文章

  1. error C2065: “M_PI”: 未声明的标识符
  2. Karto的前端实现与解读
  3. php wordpress 开源,PHP 遭弃用!WordPress.com 开源并转用 Javascript
  4. 树莓派 RespberryPi:通过命令行关机 / 重启
  5. 【坐在马桶上看算法】算法10:二叉树
  6. 自动添加html结束标志,HTML:包含或排除可选的结束标记?
  7. 【转】TeeChart的用法
  8. 信息学奥赛一本通 1839:【05NOIP提高组】谁拿了最多奖学金 | OpenJudge NOI 1.9 04:谁拿了最多奖学金 | 洛谷 P1051 [NOIP2005 提高组] 谁拿了最多奖学金
  9. mysql更改安装路径6_关于mysql安装后更改数据库路径方法-Centos6环境
  10. 使用xcode4做ios的国际化
  11. 剑指offer(C++)-JZ78:把二叉树打印成多行(数据结构-树)
  12. 设置内核的运行环境之隔离的应用程序
  13. 修复Windows 7升级Windows 10后Japanese输入法无法使用的Bug
  14. FLUENT19.0基础入门与进阶仿真分析视频教程
  15. 【避坑指“难”】react-dnd引入后,.mjs文件解析错误
  16. VMBox CentOS安装记录
  17. 粒子群算法matlab代码实例使用与参数解读(二维数据)
  18. 笔记本电脑插入耳机不能自动切换播放设备,小键盘不能自动打开,蓝屏问题记录
  19. U盘AUTO病毒删除办法
  20. 【Oracle特殊字符的处理方式】

热门文章

  1. 下列python保留字中、用于异常处理_下列Python保留字中,用于异常处理结构中用来捕获特定类型异常的是...
  2. 基于SpringBoot和MyBatisPlus的项目开发脚手架
  3. mintUI vue vue-cli
  4. MySQL 5.7以及MySQL Workbench使用
  5. 突破QQ网络硬盘共享人数限制(转)
  6. 待人友善是教养 独来独往是性格
  7. 【ENVI条件下的GF6-WFV数据处理相关问题】——想到哪里写到哪里
  8. math的向上取整_vue关于数字的处理(四舍五入,向上取整,向下取整。。)
  9. 程序员诗词大赛开始了_你看过吗?
  10. java 边读边写 文件迁移