如何从0开始编写一个网络爬虫?

导读

在开始之前,望读者提前了解过计算机网络的相关知识(尤其是HTTP协议与SSL/TLS加密)与基础的代码编写(不限于语言类型)。
以下代码均以Python3为例(因其代码简易,故使用其进行演示)
未安装Python3的请通过此连接下载安装,并配置相关的环境变量。
Download Python | Python.org

特别声明: 在正式开始编写之前,你应该明白什么资源不能爬取,如果网站有robots.txt(爬虫规则)请遵守它,否则很可能会有牢狱之灾!

正文

估计一开始接触网络爬虫的人都会听说几个爬虫库,如requestsscrapyurllib等等。
一开始我会使用requests库进行演示。

后面会教各位如何从0开始编写属于自己的爬虫库。
使用以下命令安装requests库
# Linux
pip3 install requests
# 报错的话请执行对应的安装命令安装此程序 python3-pip,或pip3
# 如果只用Python3的话请使用pip install requests

# Windows
pip install requests
# 报错请检查是否安装Python与pip,并检查环境变量是否正确配置
在安装完成之后就可以使用了,先新建一个.py文件,然后编写它。
import requests # 导入库(模块)

url = "https://cn.bing.com" # 设置网址的变量,必须是http://或https://开头
res = requests.get(url).text # 将爬取的内容保存到一个变量里面
print(res) # 显示变量的值
然后在终端使用Python执行此代码文件,你便会看到对应的输出值

此处讲解一下刚才的代码都做了什么事情。
在第一行Python导入了名为requests的模块。
第二行将网址也就是域名保存为变量。
第三行Python使用requests模块对你设定的这个域名发起了一个GET请求,并将服务器返回的HTML数据保存在了名为res的变量中。
第四行是将这个变量保存的值输出到屏幕上让你查看。
其中此代码向服务器发送的HTTP请求内容如下

GET / HTTP/1.1\r\n # 使用1.1版本HTTP协议中的GET请求访问网址的根目录
Host: cn.bing.com\r\n # 域名的值
User-Agent: python-requests/2.25.1\r\n # 客户端的设备信息
Accept-Encoding: gzip, deflate\r\n # 编码规则
Accept: */*\r\n # 客户端希望收到的数据类型,此处为不限制类型
Connection: keep-alive\r\n # 保持这个TCP连接
\r\n\r\n # 两个CRLF符结束请求(此处仅限于GET,HEAD请求等无数据请求)

requests模块为程序员提供了所有的HTTP请求方式,GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE。
也提供了非常便捷的HTTP Headers编写方式,即使用字典类型保存。
总之,requests模块是一个非常强大的库,基于urllib3模块编写。

关于requests模块的使用事项就讲到这里
接下来你该编写属于自己的爬虫库了,此处使用套接字与SSL模块
此处只会讲解最基础的形式
import socket, ssl # 导入这两个模块

host = "cn.bing.com" # 设置域名或IP地址,此处不需要加http://或https://
port = 443 # 设置端口为443,SSL/TLS专用端口,如果未配置HTTPS的服务器,请使用80端口
# 并注意端口变量类型必须为int,也就是整型

# 此处不展开讲解,你只需要理解是将TCP连接的socket赋值给了变量s
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
s = ssl.SSLContext().wrap_socket(sock, server_hostname = host)

s.settimeout(3) # 设置超时时间,当然你也可以不设置
s.connect((host, port)) # 连接对应的服务器与端口,此处是一个元组类型变量

# 编写HTTP请求头,此处只演示最基础能用的HTTP头
headers = bytes(
	"GET / HTTP/1.1\r\n" # 头部为GET请求,POST请求需要在下面加上了对应的请求数据
	"Host: " + host + "\r\n"
	"User-Agent: 123456\r\n\r\n" # 此处设备信息可以按你实际需求修改
, encoding="UTF-8")

s.sendall(headers) # 向服务器发送这个HTTP请求
res = s.recv(4096) # 接收服务器返回的数据包

print(res) # 显示返回的内容
s.close() # 关闭套接字

当你执行这个代码之后你会发现和requests模块看到的内容不一样,那是因为在requests模块中,各种信息都是经过筛选和清洗的。
在原始数据中,你看到的内容是HTTP响应头与正文内容合在一起的样子。
HTTP响应头与正文之间使用两个CRLF符进行分隔。
同时你还会注意到res变量的数据很短,这是因为你只接收了服务器发送的4096字节大小的数据,其他数据直接丢弃了。

好的,讲解完毕,有不懂的请发在评论区。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值