爬虫与网络编程基础-Task01:计算机网络基础

0x00 Abstract

为了使网络上获得的数据干净整洁,并且可以为自己的应用所用,我们得想出一些形式来表示应用与网络之间来来往往的数据。最常使用的两种技术就是:XML 和 JSON。

但是 Python 中的列表或者字典并不能在 Java 中使用(Java 中使用 HashMap),所以不能直接把 Python 中的字典传给 Java,而是应该发送 Python 与 Java 都能接受的数据。

因此,两者之间需要一种 Wire Format 来作为互相交换数据的媒介。而 XML 和 JSON 是两种比较常用的 Wire Format

0x01 Python 中创建 List

1. 创建列表

在 Pyhon 中创建一个 list,存储以下个人信息(姓名、年龄、成绩):[小王、40、50],[小贾、50、23]

# 定义列表
list = [("小王",40,50),("小贾",50,23)]

[('小王', 40,50), ('小贾', 50,23)]

2. 导入列表

如果想把 Numpy 数组转成 Json 格式,可以首先将数组转为列表。

data = data.tolist()

0x02 将数据存储为 Json 格式,并进行读取

JSON 库的一些用法

方法作用
json.dumps ()将 Python 对象编码成 Json 字符串
json.loads ()将 Json 字符串解码成 Python 对象
json.dump ()将 Python 中的对象转化成 Json 储存到文件中
json.load ()将文件中的 Json 的格式转化成 Python 对象提取

json.dump () 和 json.dumps () 的区别

  • json.dumps () 是把 Python 对象转换成 Json 对象的一个过程,生成的是字符串。
  • json.dump () 是把 Python 对象转换成 Json 对象生成一个 fp 的文件流,和文件相关。

所以后面多的一个 s 可以理解为 string

更详细的内容可以参考 Python json.dumps()函数使用解析 | w3c 笔记

1. 存储到 JSON 文件中

# 导入 json 模块
import json

# 为新建 json 文件命名
filename = 'info.json'
# 使用json.dump()方法转为json格式数据
with open(filename, 'w') as file:
    json.dump(list, file)
# 读取 json 文件
with open(filename, 'r') as file:
    info = json.load(file)

print (info)

printout: [['小王', 40,50], ['小贾', 50,23]]

Tips:

  • 默认会转为二进制数据,目前存储的 Json 文件内容为:[["\u5c0f\u738b", 40,50], ["\u5c0f\u8d3e", 50,23]]。读取的时候默认又转到了可读的 Python 对象。所以读取并打印的时候看见的是字符。
  • 如果希望文件中不使用二进制存储,通过 ensure_ascii=False 设置不转为二进制,即存储文件时:json.dump(list, file, ensure_ascii=False)

2. 编码成 JSON 字符串

# 使用 json.dumps() 方法转为json格式数据
# 注意:默认会转为二进制数据,使用 ensure_ascii=False 设置不转为二进制
json_data = json.dumps(list, ensure_ascii=False)
print (json_data)

[["小王", 40,50], ["小贾", 50,23]]

json_data = json.dumps(list)
print(json_data)

[["\u5c0f\u738b", 40,50], ["\u5c0f\u8d3e", 50,23]]

json.dumps() 也是默认编码成二进制数据。

# 打印数据类型
print(type(list))
print(type(json_data))

<class 'list'> <class 'str'>

py_data = json.loads(json_data)
print(type(py_data))

<class 'list'>

0x03 将数据存储为 XML 格式,并进行读取

XML (eXtensible Markup Language)

主要目的是帮助信息系统交换结构化数据,是一种比 JSON 要老一些的技术。

XML 代码美化工具:Pretty Printer。

XML 是一种树状结构的数据。

And you can think of this as, like folders on your computer.

我们要做的,就是从根节点,一层一层向下挖掘,找到这些数据。

更多信息可以参考: XML 教程 XML 教程 | 菜鸟教程 13.2 eXtensible Markup Language (XML) | Coursera

1. 存储为 XML 格式

首先将 List 转为字典:

index = ['0', '1'] # 这里要用 str 型
d = dict(zip(index, list))
print(d)

{'0': ('小王', 40,50), '1': ('小贾', 50,23)}

然后定义一个方法将字典转为 XML。

from xml.etree.ElementTree import Element

# Turn a simple dict of key/value pairs into XML
def dict_to_xml(tag, d):
    elem = Element(tag)
    for key, val in d.items():
        child = Element(key)
        child.text = str(val)
        elem.append(child)
    return elem
e = dict_to_xml('info', d)
print(e)

<Element 'info' at 0x0000018CA90C69A8>

或者可以使用 pip3 install dicttoxml 来转换。

2. 读取 XML 格式

转换结果是一个 Element 实例。对于 I/O 操作,使用 xml.etree.ElementTree 中的 tostring() 函数很容易就能将它转换成一个字节字符串。例如:

from xml.etree.ElementTree import tostring
tostring(e)

b"<info><0>('&#23567;&#29579;', 40,50)</0><1>('&#23567;&#36158;', 50,23)</1></info>"

目前的 e 就是一个树状结构的示例,探索一下:

print(e.tag)
print(e.text)

info None

相当于目前在 root 节点。

把子节点打印出来:

for child in e:
    print(child.tag)
    print (child.text)

0 ('小王', 40,50) 1 ('小贾', 50,23)

或者也可以将节点读取出来后,存成字典或者列表。

to_dict = {}
to_list = []
for child in e:
    to_dict[child.tag] = child.text
    
to_list.append(to_dict)

print(to_dict)
print (to_list)

{'0': "('小王', 40,50)", '1': "('小贾', 50,23)"} [{'0': "('小王', 40,50)", '1': "('小贾', 50,23)"}]

也可以使用 pip3 install xmltodict 来转换并读取。

0x04 计算机网络基础

学习 计算机网络基础 ,思考从打开 coggle.club 到网页展示,有什么步骤?

1. 网络层次分层

OSI 模型

  • OSI 概念:
    • 为了使不同计算机厂家生产的计算机能够相互通信,以便在更大的范围内建立计算机网络,国际标准化组织(ISO)在 1978 年提出了”开放系统互联参考模型",即著名的 OSI/RM 模型(Open System Interconnection/Reference Model)。“开放性”是指世界上任何地方、任何遵循 OSI 标准的系统,只要连接起来就能互相通信。
    • 注意:OSI 是一种 模型,并不是实际投入使用的协议,而是用来了解和设计网络体系结构的。
  • OSI 模型的目的:
    • 框架化;SOA。
    • 规范不同系统的互联标准,使两个不同的系统能够较容易的通信,而不需要改变底层的硬件或者软件的逻辑。
  • OSI 模型分为 7 层:
    • 将计算机网络体系结构的通信协议划分为七层,自下而上依次为:
      • 物理层(Physics Layer)
      • 数据链路层(Data Link Layer)
      • 网络层(Network Layer)
      • 传输层(Transport Layer)
      • 会话层(Session Layer)
      • 表示层(Presentation Layer)
      • 应用层(Application Layer)
    • 其中第四层完成数据传输服务,上面三层面向用户( User Support Layers)。

TCP/IP 协议

目前使用最多的是 TCP/IP 四层协议。

输入 URL 后执行的全过程

从打开 coggle.club 到网页展示,有什么步骤?

  1. DNS 域名解析:客户端浏览器通过 DNS 解析得到 Coggle 网站的 IP 地址。
  2. 客户端与服务端建立 TCP 连接:TCP 三次握手。
  3. 客户端发起 HTTP 请求:建立 TCP 连接后,把客户端信息(携带 cookies)传递给服务端。
  4. 服务端响应 HTTP 请求。
  5. 释放 TCP 连接:TCP 四次挥手。
  6. 浏览器解析 HTML 代码,并请求 HTML 代码中的资源(如图片、音频、视频、CSS、JS 等等)。
  7. 浏览器对页面进行渲染呈现给用户。

Conclusion

JSON 格式比较好理解,不多赘述。

XML 格式是一种树状结构的数据表示,数据的写入与读取都是基于这种结构的。所以首先要理解 XML 的这种内在结构,才能明白为什么 XML 的读写操作是这个样子的,否则直接照搬方法也很难清楚为什么这样做。我这里也只是浅尝辄止的了解基础概念,因为工作重心不在这,暂时不需要太深入的研究。

虽然 XML 的格式看起来跟 HTML 十分相似,但这两种格式是负责不一样的工作的。XML 被设计用来传输和存储数据。HTML 被设计用来显示数据。 而且 HTML 中使用的标签(以及 HTML 的结构)是预定义好的;而 XML 仅仅是纯文本,允许创作者定义自己的标签和自己的文档结构。也就是说是针对自己的应用自行设计标签与结构,使得能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。

之前学过的计算机网络基础大部分都还给老师了,只是模糊地记得一些概念,但要我去说每个层或者每种协议里面传输了哪些数据,数据分为哪几种,各自负责什么功能,或者计算一下 IP 已经是想不起来了。这次先复习一下 OSI 和 TCP/IP 的基本结构。

References

Json 读写: Python 中如何将数据存储为 json 格式的文件 Python json.dumps()函数使用解析 | w3c 笔记 Python json 模块 dumps、dump、loads、load 的使用

XML 读写: XML 简介 13.2 eXtensible Markup Language (XML) | Coursera 使用 Python 读写 XML 文件 | Zh 某的备忘录 【一起学 Python·网络爬虫】XML 简介与解析 | bilibili Python 列表转字典 字典和列表相互转换 6.5 将字典转换为 XML — python3-cookbook 3.0.0 文档 使用两个三方库来读写

计算机网络基础: OSI、TCP/IP、计算机基础、操作系统 | bilibili 计算机基础知识 | bilibili 图解 OSI 七层模型 计算机网络基础

输入 URL 后执行的全过程: 这里的三次握手,四次挥手讲的很清楚。 ⭐⭐⭐ 输入 URL 后的全部过程 会用到哪些协议? 结合协议来讲,每个步骤在哪一层