正常情况下的浏览器查询信息的底层步骤:
1、浏览器发送一个请求对象,此对象包含请求头部和信息体两个部分,头部主要包括本机的MAC地址信息、想要访问的对象的IP信息等基本信息,信息体则是想要访问的内容部分
2、信息从本机ip发出后,流转到本机的网关,本机网关在请求对象上加上自己的一些信息,然后根据tcp/ip协议将其打包切成许多份发送到网络上
3、通常从本机的网关发出后不会直接由目标服务器接收,而是会经过多个代理服务器,代理服务器在收到信息后,同样会添加自己的一些信息后继续发送到下一个代理服务器
4、服务器接收到信息包后会与本机验证,验证通过后解析信息包,并返回信息包的请求对象,然后将返回的对象如上步骤发回本机,浏览器对返回的信息解析后展示到前端
本质上爬虫与浏览器并无差异,都是通过访问目标服务器来获取所需的信息
简单的爬虫示例
from urllib.request import urlopen
path='http://xxxx.xxx.xxx'
html=urlopen(path)
print(html.read())
BS4版的简单爬虫示例
from urllib.request import urlopen
from bs4 import BeautifulSoup
path='http://xxxx.xxx.xxx'
html=urlopen(path)
bsobj=BeautifulSoup(html.read(),'lxml')
print(bsobj)
beautifulsoup把一个html对象转换为beautifulsoup对象,可以轻易用标签、正则或者函数读取特定信息
撸代码的时候请记得要设置好处理异常和错误
访问某一服务器的某个页面时可能会出现如下错误:
1、页面不存在
2、服务器不存在
异常1经常以404或者500的信息码方式出现,会抛出HTTPError异常,可以用except捕获
异常2会返回一个None的对象,此时可以用if else条件来判断返回对象是否为None
from urllib.request import urlopen
from bs4 import BeautifulSoup
path='http://xxxx.xxx.xxx'
try:
html=urlopen(path)
except HTTPError as e:
return None
try:
bsobj=BeautifulSoup(html.read(),'lxml')
except AttributeError as e:
return None
由于bs对象可能是以一个None对象存在,那么当需要提取html对象的子节点的信息时,例如h1、p等,上述的第二个try、except会返回错误,因为None type是没有任何其他子节点的属性的,因此要再加以判断,并且上述内容可以用函数封装
上述代码修改为:
from urllib.request import urlopen
from bs4 import BeautifulSoup
def read_url(url):
try:
html=urlopen(url)
except HTTPError as e:
return None
try:
bsobj=BeautifulSoup(html.read(),'lxml')
title=bsobj.body.h1
except AttributeError as e:
return None
return title
title=read_url('http://xxxx.xxx.xxx')
if title is None:
print('xxxxx')
else:
print(title)