目录

Web请求流程

常⻅的⻚⾯渲染过程:

requests库

get请求方式:

post请求方式:

JSON基本使用:

数据解析

re解析(正则表达式)

bs4解析

xpath解析

requests进阶

模拟浏览器登录—处理cookie

防盗链处理

代理—防止封IP


Web请求流程

常⻅的⻚⾯渲染过程:

1.服务器渲染

这个最容易理解, 也是最简单的. 含义呢就是我们在请求到服务器的时候, 服务器直接把数据全部写⼊到html中, 我们浏览器就能直接拿到带有数据的html内容.

2.前端JS渲染

这种就稍显麻烦了. 这种机制⼀般是第⼀次请求服务器返回⼀堆HTML框架结构. 然后再次请求到真正保存数据的服务器, 由这个服务器返回数据, 最后在浏览器上对数据进⾏加载. 就像这样:

requests库

get请求方式:

# 安装requests
# pip install requests
# 国内源 /清华源/阿里元/豆瓣元
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
#浏览器地址栏全部用的get请求方式
import requestsquery = input("输入一个你喜欢的明星")#f'String'  把变量query塞到字符串里去
url = f'https://www.sogou.com/web?query={query}'dic = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}
# get方式请求url,响应过来的东西赋值给resp
#设置get请求的headers参数,把浏览器正常的User-Agent进行请求
resp = requests.get(url, headers=dic)# 处理一个小小的反爬print(resp)
print(resp.text)  # 打印页面源代码
#百度检测到我们不是正常浏览器访问,我们需要伪装的更像浏览器,
# 我们去浏览器抓包工具进行设置,进入浏览器F12-Network-Headers(请求头)-
# User-Agent(用来描述你当前的请求是通过哪一个设备发出),
# 把浏览器正常访问User-Agent的值复制过来,在程序中进行设置

post请求方式:

#此程序以post请求方式为例,打开百度翻译主页面,在英语翻译框输入要翻译的英语单词
#的时候,F12-Network-会出现sug请求链接,再点开Preview(预览),会得到一些数据,
# 这些数据就是我们输入英语单词的时候服务器返回给我们的内容。#第一次请求只要一个html骨架. 第二次请求拿到数据. 进行数据展示.
#   在页面源代码中, 看不到数据import requestsurl = "https://fanyi.baidu.com/sug"s = input("请输入你要翻译的英文单词")
dat = {"kw": s
}# 发送post请求, 发送的数据必须放在字典中, 通过data参数进行传递
resp = requests.post(url, data=dat)
print(resp.json())  # 将服务器返回的内容直接处理成json()  => dictresp.close()  # 关掉resp

JSON基本使用:

1.JSON介绍

  • JSON,全称是 JavaScript Object Notation,即 JavaScript对象标记法。
  • JSON是一种轻量级(Light-Meight)、基于文本的(Text-Based)、可读的(Human-Readable)格式。
  • JSON 的名称中虽然带有JavaScript,但这是指其语法规则是参考JavaScript对象的,而不是指只能用于JavaScript 语言。
  • JSON无论对于人,还是对于机器来说,都是十分便于阅读和书写的,而且相比 XML(另一种常见的数据交换格式),文件更小,因此迅速成为网络上十分流行的交换格式。

2.JSON 语法

  • 数组(Array)用方括号(“[]”)表示。
  • 对象(0bject)用大括号(“{}”)表示。
  • 名称/值对(name/value)组合成数组和对象。
  • 名称(name)置于双引号中,值(value)有字符串、数值、布尔值、null、对象和数组。
  • 并列的数据之间用逗号(“,”)分隔
{"name": "xdr630","favorite": "programming"
}

数据解析

在上⼀章中, 我们基本上掌握了抓取整个⽹⻚的基本技能. 但是呢, ⼤多数情况下, 我们并不需要整个⽹⻚的内容, 只是需要那么⼀⼩部分.怎么办呢? 这就涉及到了数据提取的问题.

本课程中, 提供三种解析⽅式:
1. re解析(正则表达式)
2. bs4解析
3. xpath解析

这三种⽅式可以混合进⾏使⽤, 完全以结果做导向, 只要能拿到你想要的数据. ⽤什么⽅案并不重要. 当你掌握了这些之后. 再考虑性能的问题.

re解析(正则表达式)

Regular Expression, 正则表达式, ⼀种使⽤表达式的⽅式对字符串进⾏匹配的语法规则.

正则的语法: 使⽤元字符进⾏排列组合⽤来匹配字符串

应用场景:

1.验证:表单提交时,进行用户名密码的验证。

2.查找:从大量信息中快速提取指定内容,在一批url中,查找指定url。

3.替换:将指定格式的文本进行正则匹配查找,找到之后进行特定替换。元字符: 具有固定含义的

  • 特殊符号 常⽤元字符:
. 匹配除换⾏符以外的任意字符
\w 匹配字⺟或数字或下划线
\s 匹配任意的空⽩符
\d 匹配数字
\n 匹配⼀个换⾏符
\t 匹配⼀个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配⾮字⺟或数字或下划线
\D 匹配⾮数字
\S 匹配⾮空⽩符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
  • 量词: 控制前⾯的元字符出现的次数
* 重复零次或更多次
+ 重复⼀次或更多次
? 重复零次或⼀次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次\d\d\d\d相当于\d{4}\d+   可以出现⼀次或更多次数字\d?   出现数字或者不出现数字
  • 贪婪匹配和惰性匹配
.* 贪婪匹配    的意思是:(.)除换行符以外任意字符  尽可能多的匹配.*? 惰性匹配   的意思是:(.)除换行符以外任意字符 (?)出现零次或多次 尽可能少的匹配
  • 正则练习

开源中国—在线正则表达式

re模块在Python中的应用

1. findall 查找所有. 返回list

2. search 会进⾏匹配. 但是如果匹配到了第⼀个结果. 就会返回这
个结果. 如果匹配不上search返回的则是None

3. match 只能从字符串的开头进⾏匹配

4. finditer, 和findall差不多. 只不过这时返回的是迭代器(重点)

5. compile() 可以将⼀个⻓⻓的正则进⾏预加载. ⽅便后⾯的使⽤

6. 正则中的内容如何单独提取?
单独获取到正则中的具体内容可以给分组起名字

import re# # findall:  匹配字符串中所有的符合正则的内容
# lst = re.findall(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
#字符串前加 r:去掉反斜杠的转移机制。
# print(lst)
#
# # finditer: 匹配字符串中所有的内容[返回的是迭代器], 从迭代器中拿到内容需要.group()
# it = re.finditer(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# for i in it:
#     print(i.group())# # search, 找到一个结果就返回, 返回的结果是match对象. 拿数据需要.group()
# s = re.search(r"\d+", "我的电话号是:10086, 我女朋友的电话是:10010")
# print(s.group())# # match是从头开始匹配
# s = re.match(r"\d+", "10086, 我女朋友的电话是:10010")
# print(s.group())# # 预加载正则表达式,我们写的这个正则表达式比较常用
# obj = re.compile(r"\d+")
#
# ret = obj.finditer("我的电话号是:10086, 我女朋友的电话是:10010")
# for it in ret:
#     print(it.group())
#
# ret = obj.findall("呵呵哒, 我就不信你不还我1000000000")
# print(ret)s = """
<div class='jay'><span id='1'>郭麒麟</span></div>
<div class='jj'><span id='2'>宋铁</span></div>
<div class='jolin'><span id='3'>大聪明</span></div>
<div class='sylar'><span id='4'>范思哲</span></div>
<div class='tory'><span id='5'>胡说八道</span></div>
"""# (?P<分组名字>正则) 可以单独从正则匹配的内容中进一步提取内容
#(?P<wahaha>.*?)    的意思是 .*?匹配到的内容会赋值给<>里的wahaha
#(?P<id>\d+)    的意思是   \d+ 匹配到的内容会赋值给<>里的id
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<wahaha>.*?)</span></div>", re.S)  # re.S: 让.能匹配换行符result = obj.finditer(s)
for it in result:print(it.group("wahaha"))print(it.group("id"))

bs4解析

bs4模块安装

在python中我⼀般只推荐⽤pip进⾏安装.

 pip install bs4

如果安装的速度慢, 建议更换国内源(推荐阿⾥源或者清华源)

pip install -i
https://pypi.tuna.tsinghua.edu.cn/simple bs4

bs使用案例

bs4在使⽤的时候就需要参照⼀些html的基本语法来进⾏使⽤了. 我们直接上案例哈. 案例是最能直观的展现出bs4的便捷效果的.我们来尝试抓取北京新发地市场的农产品价格. http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml

1.先获取⻚⾯源代码. 并且确定数据就在⻚⾯源代码中~

2.将⻚⾯源代码丢给BeautifulSoup, 然后我们就可以通过bs对象
去检索⻚⾯源代码中的html标签了

3.BeautifulSoup对象获取html中的内容主要通过find()/find_all()这两个⽅法来完成

不论是find还是find_all 参数⼏乎是⼀致的.find()查找1个. find_all()查找⻚⾯中所有的.

意思是在⻚⾯中查找 xxx标签, 并且标签的xxx属性必须是xxx值

# 安装
# pip install bs4 -i 清华# 1. 拿到页面源代码
# 2. 使用bs4进行解析. 拿到数据
import requests
from bs4 import BeautifulSoup
#导入csv文件库
import csv# CSV是一种以逗号分隔数值的文件类型,在数据库或电子表格中,
# 常见的导入导出文件格式就是CSV格式,CSV格式存储数据通常以纯文本的方式存数数据表。url = "http://www.xinfadi.com.cn/marketanalysis/0/list/1.shtml"
resp = requests.get(url)f = open("菜价.csv", mode="w")
csvwriter = csv.writer(f)
#使用csv.writer()创建csv文件# 解析数据
# 1. 把页面源代码交给BeautifulSoup进行处理, 生成bs对象
page = BeautifulSoup(resp.text, "html.parser")  # 指定html解析器
# 2. 从bs对象中查找数据
# find(标签, 属性=值)就找第一个
# find_all(标签, 属性=值)找所有
# table = page.find("table", class_="hq_table")  # class是python的关键字
table = page.find("table", attrs={"class": "hq_table"})  # 和上一行是一个意思. 此时可以避免class
# 拿到所有数据行,并获取每一个tr行,[1:]表示从获取第二行开始
# tr表格每行,可用于包裹td
# td表格单元格,可用于包裹内容
trs = table.find_all("tr")[1:]#在Python中,切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,
# 通过切片操作,可以生成一个新的序列。
#切片语法:sname[start : end : step]
# sname:表示序列的名称。
# start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,
# 也就是从序列的开头进行切片。
# end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度。
# step:表示在切片的步长。如果省略,则默认步长为1。若省略步长,
# 则最后一个冒号就可以省略。for tr in trs:  # 每一行tds = tr.find_all("td")  # 拿到每行中的所有tdname = tds[0].text  # .text 表示拿到被标签标记的内容low = tds[1].text  # .text 表示拿到被标签标记的内容avg = tds[2].text  # .text 表示拿到被标签标记的内容high = tds[3].text  # .text 表示拿到被标签标记的内容gui = tds[4].text  # .text 表示拿到被标签标记的内容kind = tds[5].text  # .text 表示拿到被标签标记的内容date = tds[6].text  # .text 表示拿到被标签标记的内容# 上面已经创建csvwriter对象,使用.writerow进行调用csvwriter.writerow([name, low, avg, high, gui, kind, date])f.close()
print("over1!!!!")

xpath解析

XPath是⼀⻔在 XML ⽂档中查找信息的语⾔. XPath可⽤来在 XML⽂档中对元素和属性进⾏遍历. ⽽我们熟知的HTML恰巧属于XML的⼀个⼦集. 所以完全可以⽤xpath去查找html中的内容.

在python中想要使⽤xpath, 需要安装lxml模块.

pip install lxml

用法:

将要解析的html内容构造出etree对象.

使⽤etree对象的xpath()⽅法配合xpath表达式来完成对数据的提取

# xpath 是在XML文档中搜索内容的一门语言
# html是xml的一个子集# 安装lxml模块
# pip install lxml
# xpath解析
from lxml import etreexml = """
<book><id>1</id><name>野花遍地香</name><price>1.23</price><nick>臭豆腐</nick><author><nick id="10086">周大强</nick><nick id="10010">周芷若</nick><nick class="joy">周杰伦</nick><nick class="jolin">蔡依林</nick><div><nick>热热热热热1</nick></div><span><nick>热热热热热2</nick></span></author><partner><nick id="ppc">胖胖陈</nick><nick id="ppbc">胖胖不陈</nick></partner>
</book>
"""tree = etree.XML(xml)
# result = tree.xpath("/book")  # /表示层级关系. 第一个/是根节点
# result = tree.xpath("/book/name")
# result = tree.xpath("/book/name/text()")  # text() 拿文本
# result = tree.xpath("/book/author//nick/text()")
#  // 后代,就是author下所有的nick节点里的文本
# result = tree.xpath("/book/author/*/nick/text()")
#  * 任意的节点. 通配符  就是在author下div/span或其他任意节点里的nick节点
result = tree.xpath("/book//nick/text()")
print(result)

X-path练习

from lxml import etreetree = etree.parse("b.html")
#etree.parse直接接受一个文档,按照文档结构解析(本地文件)
#etree.html可以解析html文件:(服务器上返回的html数据)# result = tree.xpath('/html')
# result = tree.xpath("/html/body/ul/li/a/text()")
# result = tree.xpath("/html/body/ul/li[1]/a/text()")
#  xpath的顺序是从1开始数的, []表示索引# result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()")
#  [@xxx=xxx] 属性的筛选# print(result)# ol_li_list = tree.xpath("/html/body/ol/li")
#
# for li in ol_li_list:
#     # 从每一个li中提取到文字信息
#     result = li.xpath("./a/text()")  # 在li中继续去寻找. 相对查找
#     print(result)
#     result2 = li.xpath("./a/@href")  # 拿到属性值: @属性
#     print(result2)
#
# print(tree.xpath("/html/body/ul/li/a/@href"))print(tree.xpath('/html/body/div[1]/text()'))#['李嘉诚']
print(tree.xpath('/html/body/ol/li/a/text()'))#['飞机', '大炮', '火车']

b.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Title</title></head><body><ul><li><a href="http://www.baidu.com">百度</a></li><li><a href="http://www.google.com">谷歌</a></li><li><a href="http://www.sogou.com">搜狗</a></li></ul><ol><li><a href="feiji">飞机</a></li><li><a href="dapao">大炮</a></li><li><a href="huoche">火车</a></li></ol><div class="job">李嘉诚</div><div class="common">胡辣汤</div></body>
</html>

猪八戒网案例

# 拿到页面源代码
# 提取和解析数据
import requests
from lxml import etreeurl = "https://beijing.zbj.com/search/f/?type=new&kw=saas"
resp = requests.get(url)
# print(resp.text)# 解析
html = etree.HTML(resp.text)
#etree.parse直接接受一个文档,按照文档结构解析(本地文件)
#etree.html可以解析html文件:(服务器上返回的html数据)# 拿到每一个服务商的div
divs = html.xpath("/html/body/div[6]/div/div/div[2]/div[4]/div[1]/div")
for div in divs:  # 每一个服务商信息price = div.xpath("./div/div/a[1]/div[2]/div[1]/span[1]/text()")[0].strip("¥")#[0].strip("字符")   从列表第一个元素去掉列表里字符串里的字符title = "saas".join(div.xpath("./div/div/a[1]/div[2]/div[2]/p/text()"))# "字符a".join(字符串A)  使用"字符a"作为分隔符,将字符串A连接成字符串com_name = div.xpath("./div/div/a[2]/div[1]/p/text()")[0]location = div.xpath("./div/div/a[2]/div[1]/div/span/text()")[0]print(com_name)

requests进阶

模拟浏览器登录—处理cookie

# 登录 -> 得到cookie
# 带着cookie 去请求到书架url -> 书架上的内容# 必须得把上面的两个操作连起来
# 我们可以使用session进行请求 -> session你可以认为是一连串的请求.
# 在这个过程中的cookie不会丢失
import requests# # 会话
session = requests.session()
data = {"loginName": "18614075987","password": "q6035945"
}
#
# # 1. 登录
url = "https://passport.17k.com/ck/user/login"
session.post(url, data=data)
# print(resp.text)
# print(resp.cookies)  # 看cookie# # 2. 拿书架上的数据
# # 刚才的那个session中是有cookie的
resp = session.get('https://user.17k.com/ck/author/shelf?page=1&appKey=2406394919')print(resp.json())print(resp.text)

防盗链处理

注:谷歌浏览器查看页面源代码和检查是不一样的,查看页面源代码能看到服务器渲染的HTML, 有些视频或者其他资源是后期通过JS/页面脚本生成的,是前端JS渲染得到的,也就是二次请求加载数据组装,通过检查看到的代码就是浏览器完成全部请求加载好的。

# 1. 拿到contId
# 2. 拿到videoStatus返回的json. ->  srcURL
# 3. srcURL里面的内容进行修整
# 4. 下载视频
import requests# 拉取视频的网址
url = "https://www.pearvideo.com/video_1721605"
contId = url.split("_")[1]
#通过下划线切割字符串取第二个元素
videoStatusUrl = f"https://www.pearvideo.com/videoStatus.jsp?contId={contId}"headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36",# 防盗链: 溯源, 当前本次请求的上一级是谁"Referer": url
}resp = requests.get(videoStatusUrl, headers=headers)
dic = resp.json()srcUrl = dic['videoInfo']['videos']['srcUrl']
systemTime = dic['systemTime']#替换的数字
srcUrl = srcUrl.replace(systemTime, f"cont-{contId}")
#f"字符串{想要替换字符串的变量(这个变量已经被赋值)}"
# 例:
# >>>name = 'xiaoming'
# >>> age = 18
# >>> f"hi, {name}, are you {age}"
#输出:'hi, xiaoming, are you 18'# 下载视频
with open("a.mp4", mode="wb") as f:f.write(requests.get(srcUrl).content)# 文件的读操作
# with open(r'filename.txt') as f:
#     data_user = pd.read_csv(f)  # 文件的读操作
#
# 文件的写操作,
# with open('data.txt'(文件名), 'w'(文件的写入模式)) as f:
#     f.write('hello world')  也可以是视频/图片/音频链接的内容

代理—防止封IP

当我们反复抓取⼀个⽹站时, 由于请求过于频繁, 服务器很可能会将你的IP进⾏封锁来反爬. 应对⽅案就是通过⽹络代理的形式进⾏伪装.

# 原理. 通过第三方的一个机器去发送请求
import requests# 218.60.8.83:3129
proxies = {"https": "https://218.60.8.83:3129"
}resp = requests.get("https://www.baidu.com", proxies=proxies)
resp.encoding = 'utf-8'
print(resp.text)

Python爬虫(1)相关推荐

  1. 关于Python爬虫原理和数据抓取1.1

    为什么要做爬虫? 首先请问:都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据 ...

  2. python爬虫之Scrapy框架的post请求和核心组件的工作 流程

    python爬虫之Scrapy框架的post请求和核心组件的工作 流程 一 Scrapy的post请求的实现 在爬虫文件中的爬虫类继承了Spider父类中的start_urls,该方法就可以对star ...

  3. python爬虫抓取信息_python爬虫爬取网上药品信息并且存入数据库

    我最近在学习python爬虫,然后正好碰上数据库课设,我就选了一个连锁药店的,所以就把网上的药品信息爬取了下来. 1,首先分析网页 2,我想要的是评论数比较多的,毕竟好东西大概是买的人多才好.然后你会 ...

  4. python爬虫案例_推荐上百个github上Python爬虫案例

    现在学生都对爬虫感兴趣,这里发现一些好的github开源的代码,分享给各位 1.awesome-spider 该网站提供了近上百个爬虫案例代码,这是ID为facert的一个知乎工程师开源的,star6 ...

  5. Python培训分享:python爬虫可以用来做什么?

    爬虫又被称为网络蜘蛛,它可以抓取我们页面的一些相关数据,近几年Python技术的到来,让我们对爬虫有了一个新的认知,那就是Python爬虫,下面我们就来看看python爬虫可以用来做什么? Pytho ...

  6. 玩转 Python 爬虫,需要先知道这些

    作者 | 叶庭云 来源 | 修炼Python 头图 | 下载于视觉中国 爬虫基本原理 1. URI 和 URL URI 的全称为 Uniform Resource Identifier,即统一资源标志 ...

  7. 买不到口罩怎么办?Python爬虫帮你时刻盯着自动下单!| 原力计划

    作者 | 菜园子哇 编辑 | 唐小引 来源 | CSDN 博客 马上上班了,回来的路上,上班地铁上都是非常急需口罩的. 目前也非常难买到正品.发货快的口罩,许多药店都售完了. 并且,淘宝上一些新店口罩 ...

  8. 一个月入门Python爬虫,轻松爬取大规模数据

    如果你仔细观察,就不难发现,懂爬虫.学习爬虫的人越来越多,一方面,互联网可以获取的数据越来越多,另一方面,像 Python这样一个月入门Python爬虫,轻松爬的编程语言提供越来越多的优秀工具,让爬虫 ...

  9. Python爬虫获取文章的标题及你的博客的阅读量,评论量。所有数据写入本地记事本。最后输出你的总阅读量!

    Python爬虫获取文章的标题及你的博客的阅读量,评论量.所有数据写入本地记事本.最后输出你的总阅读量!还可以进行筛选输出!比如阅读量大于1000,之类的! 完整代码在最后.依据阅读数量进行降序输出! ...

  10. Python爬虫破解有道翻译

    有道翻译是以异步方式实现数据加载的,要实现对此类网站的数据抓取,其过程相对繁琐,本节我以有道翻译为例进行详细讲解. 通过控制台抓包,我们得知了 POST 请求的参数以及相应的参数值,如下所示: 图1: ...

最新文章

  1. 向页面中添加音乐或flash
  2. 【PC工具】更新win10关闭更新工具及注意事项
  3. oracle层次化查询
  4. 关于大型网站技术演进的思考(六)--存储的瓶颈(6)
  5. Linux用命令获取广域网(公网)IP地址
  6. 机器学习介绍jc01
  7. 【LOJ】 #2521. 「FJOI2018」领导集团问题
  8. Windows下python安装pymyssql报错
  9. 提高迅雷下载速度 超好用,下载速度实实在在的提高了!
  10. Windows邮件添加QQ邮箱
  11. 完美的支持Retina MACBOOK的股票软件-富图牛牛
  12. 国庆假期看了一系列图像分割Unet、DeepLabv3+改进期刊论文,总结了一些改进创新的技巧
  13. Xcode 使用 code snippets (代码块)Xcode 11以上
  14. 经典按键java手机游戏_盘点曾经红极一时的手机游戏,每款都是经典中的经典...
  15. 2、气体灭火系统的设计灭火浓度
  16. mongodb基础入
  17. 关于公正执法的一点想法
  18. 第八章【ADFS集成Exchang实现OWA\ECP单点登录SSO】配置Exchange OWA认证方式为ADFS***(本栏目重点)
  19. 欠料、品质问题频发,PMC该怎么做?
  20. Scratch的基础使用

热门文章

  1. Flexbox布局基础入门
  2. MSN Messenger协议 【 very cool stuff 】
  3. vue中用js将json数据按英文字母顺序进行排序
  4. mapreduce推测执行算法及原理
  5. ubuntu20.04安装常用的软件
  6. 客户关系管理:CRM战略
  7. 华为--三层交换实验(原理与实验详情)
  8. 苹果内购 订单验证 21002 坑
  9. 中国传统的节日(端午节)
  10. 网易微专业python数据分析_网易微专业_Python数据分析师 01 数据思维导论:如何从数据中挖掘价值?...