友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。
Socket定义:
Socket获取网络数据的四个步骤:
socket.socket函数的前两个参数的默认值是socket.AF_INET和socket.SOCK_STREAM,创建TCP socket时可以直接写成socket.socket()。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
注意没有前缀http或https
s.connect(('www.baidu.com', 80))
发送数据有两个方法send和sendall
data = "something you want to send"
s.sendall(data)
当连接不再需要时可以使用close关闭socket连接,关闭后的连接不能再进行任何操作。
s.close()
进阶提示: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.netloc
path = url.path
if 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 += data
else:
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")
Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。
首先我们需要安装Requests包:pip install requests
大部分response.text返回的是Unicode格式,通常需要转换为utf-8格式,否则就是乱码。这时我们可以通过以下两种方式转码:
请求方式包括多种,GET请求、POST请求、PUT请求、DELETE请求等,可以理解为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,增,改,删4个操作。
请求类型 | 请求类型的说明文档 |
GET请求 | GET请求用来查询数据,不会修改、增加数据,不会影响资源内容。 |
POST请求 | POST请求一般是对服务器的数据做改变,常用于数据的提交、新增操作。 |
PUT请求 | PUT请求的侧重点在于对于数据的修改操作。 |
DELETE请求 | DELETE请求一般用来删除某一个资源的。 |
import requests
response = requests.get(url="https://www.baidu.com")
response.content.decode("utf-8")
'\r\n 百度一下,你就知道 \r\n'
进阶提示:
请求头中(http请求中的header部分)的编码方式content-type一般包括:
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"
}
文件会转为Byte格式,放入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"
}
设置必须在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(, 'Connection to httpbin.org timed out. (connect timeout=0.1)'))"))
Cookie 能够保存有关访问者的信息。更概括地说,Cookie 是一种保持 Web 应用程序连续性的方法。因此 Cookie 的作用就类似于名片,它提供了相关的标识信息,可以帮助应用程序确定如何继续执行。例如一些要求用户登录的站点则可以通过 Cookie 来确定您是否已经登录过,这样您就不必每次都输入账号密码。
cookie和session区别:
import requests
response = requests.get('https://www.baidu.com')
print(response.cookies)
for key,value in response.cookies.items():
print(key,'==',value)
]>
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"
}
}
API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数、HTTP接口),或指软件系统不同组成部分衔接的约定。用来提供应用程序与开发人员基于某软件或硬件得以访问的一组例程,而又无需访问源码,或理解内部工作机制的细节。
import requests
import json
response = requests.get("https://api.oioweb.cn/api/common/history")
r = json.loads(response.text)
for index,info in enumerate(r["result"],1):
print("{}:{}-{}".format(index,info["year"],info["title"]))
1:290-西晋开国皇帝晋武帝司马炎逝世
2:762-唐朝皇帝唐肃宗李亨逝世
3:1375-明朝政治家刘伯温逝世
4:1787-德国物理学家乔治·欧姆诞生于德国巴伐利亚埃尔朗根城
5:1940-中华民国国军将军张自忠在与日军战斗中壮烈殉国
6:1941-《解放日报》在延安创刊
7:1947-第二次国共内战孟良崮战役结束
8:1951-日本声优石冢运升出生
9:1953-美国男演员皮尔斯·布鲁斯南出生
10:1958-美国第二通讯社合众国际社建成
11:1958-中国“大跃进”运动全面展开
12:1960-梅曼在休斯研究实验室首次产生光学雷射
13:1969-苏联宇宙飞船到达金星
14:1997-中国当代散文家汪曾祺逝世
15:2013-英格兰著名球星贝克汉姆通过英足总官网宣布退役
import requests
r = requests.get(url="https://api.oioweb.cn/api/txt/dict?text=躺")
r.encoding="utf-8"
print(r.text)
{“code”:200,“result”:{“hanzi”:“躺”,“pinyin”:“tǎng”,“bihua”:“15”,“bushou”:“身”,“wubi”:“”,“basic_explain”:[“躺”,“tǎng”,“笔画数:15”,“部首:身”,“笔顺编号:325111324325251”],“detail_explain”:[“详细字义”,“◎ 躺 tǎng”,“〈动〉”,“同本义 [lie;recline]”,“这无耻的畜生想必是躺尸了。——清· 忧患余生《邻女语》”,“又如:躺在床上;躺着歇歇;躺尸;躺桥”,“停止劳动或努力 [rest]。如:不要躺在过去的成绩上睡大觉”,“引伸指物体平放或倒伏在地 [lie flat]。如:荒草躺倒在烂泥里”,“死的婉辞 [die]”,“先母躺了下来,还是很热闹的。——《二十年目睹之怪现状》”],“words”:"躺倒 躺卧 躺椅 "},“msg”:“success”}
我们通过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":"钱买不到快乐是假的,你那点钱买不到快乐是真的。"}
钱买不到快乐是假的,你那点钱买不到快乐是真的。
我们通过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': '域名已被注册'}
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包,用来快速处理数据
城市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(city.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
近三天天气预报接口为 "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
{
"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']}
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 |
网络爬虫又称网络蜘蛛、网络蚂蚁、网络机器人等,可以自动化浏览网络中的信息,当然浏览信息的时候需要按照我们制定的规则进行,这些规则我们称之为网络爬虫算法。使用Python可以很方便地编写出爬虫程序,进行互联网信息的自动化检索。
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
获取弹幕网址操作顺序如下:
接下来,根据弹幕网址,爬取弹幕数据。
import requests
crawler = requests.get("https://comment.毕里毕里.com/430717173.xml")
crawler.encoding='utf-8'
crawler.text
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]#因为数据量大,我们取前十个
['回忆', '可能', '别说', '什么', '绝对', '没死', '哈德森', '太太', '我姐', '区区']
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) #展示词云
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")#名侦探柯南
您的代码:
您的代码:
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')
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 = 0
for i in range(n+1):
total+=i
return total
n = int(input("请输入n的值\n:"))
print(sums(n))
请输入n的值
:1000001
2022-06-07 14:41:14,306 - INFO - 统计0至1000001相加之和程序开始!
2022-06-07 14:41:14,307 - ERROR - 1000001大于100万!
500001500001