文章目录
爬虫介绍
-
爬虫定义:网络爬虫,又被称为网页蜘蛛,网络机器人,是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。
-
两大特征:
- 能按照作者要求下载数据或者内容
- 能自动在网络上流窜
-
三大步骤:
- 下载网页
- 提取正确的信息
- 根据一定规则自动跳到另外的网页上执行上两布工作
-
爬虫分类
- 通用爬虫:把网页上的内容全部宕下来
- 专有爬虫:(聚焦爬虫)
-
Python网络包介绍
- Python2.x:urllib, urllib2,urllib3, httplib, httplib2, requests
- Python3.x: urllib, urllib3, httplib2, requests
- Python2: urllib和urllib3配合使用,或者requests
- Python3:urllib和requests
urllib模块使用
- 包含模块
- urllib.request:打开和读取urls
- urllib.error:包含urllib.request产生的常见的错误,使用try捕捉
- urllib.parse:包含解析url的方法
- urllib.robotparse: 解析robots.txt文件
from urllib import request
if __name__ == '__main__':
url = ""
# 打开相应的url并把相应网页作为返回
rsp = request.urlopen(url)
# 把返回结果读取出来
# 读取出来的时bytes流
html = rsp.read()
# 解码
html = html.decode()
print(html)
- 网页编码问题的解决
- chardet: 可以自动检测网页文件的编码格式,但是可能有误
- 需要安装:conda install chardet
# 利用request下载页面,自动检测网页编码格式
import urllib
import chardet
if __name__ == '__main__':
url = ""
rsp = urllib.request.urlopen(url)
html = rsp.read()
cs = chardet.detect(html)
print(type(cs))
print(cs)
# 使用get取值保证不会出错
html = html.decode(cs.get("encoding", "utf-8"))
print("html")
- urlopen 的返回对象
- geturl:返回请求对象的url
- info: 请求反馈对象的mate信息
- getcode:返回http code
import urllib
import chardet
if __name__ == '__main__':
url = ""
rsp = urllib.request.urlopen(url)
# 查看rsp的返回类型
print(type(rsp))
print(rsp)
# 查看相关函数的使用
print("URL:{0}".format(rsp.geturl()))
print("Info:{0}".format(rsp.info()))
print("Code:{0}".format(rsp.getcode()))
html = rsp.read()
cs = chardet.detect(html)
# 使用get取值保证不会出错
html = html.decode(cs.get("encoding", "utf-8"))
print("html")
- request.data 的使用
from urllib import request, parse
import chardet
if __name__ == '__main__':
url = "http://www.baidu.com/s?"
wd = input("Input your keyword")
# 想要使用data,需要字典结构
qs = {"wd": wd}
# 转换url编码
qs = parse.urlencode(qs)
print(qs)
fullurl = url + qs
print(fullurl)
rsp = request.urlopen(fullurl)
html = rsp.read()
cs = chardet.detect(html)
# 使用get取值保证不会出错
html = html.decode(cs.get("encoding", "utf-8"))
print("html")
- 访问网络的两种方式
- get
- 利用参数给服务器传递参数
- 数据为dict,然后用parse编码
- post
- 一般向服务器传递参数使用
- post是把信息自动加密
- 想用post信息,需要data参数
- 使用post,意味着http的请求头可能要更改
- Content-Type:application/x-www.form-urlencode
- Content-Length: 数据长度
- 简而言之:一旦请求变更,注意其他请求头信息的相适应
- urllib.parse.urlencode 字符串编码
- get
'''
利用parse模块模拟post请求
分析百度词典
步骤:
1. 打开F12
2. 尝试输入单词girl,发现每敲一个单词,都有一个请求
3. 请求地址是:http://fanyi.baidu.com/sug
4. 利用Network-All-Hearders-查看,发现fromdata的值是 kw:girl
5. 查看返回格式:是json格式,导入json包
'''
from urllib import parse, request
import json
'''
大致流程:
1. 利用data构造内容,然后urlopen打开
2. 返回一个json格式的结果
3. 结果就应该是girl的释义
'''
baseurl = 'http://fanyi.baidu.com/sug'
# 存放用来模拟fromdata的数据一定是dict格式
data = {
'kw': 'girl'
}
# 需要使用parse模块对data进行编码,最后编码为bytes流
data = parse.urlencode(data).encode("utf-8")
print(type(data))
# 构造一个请求头,至少包含数据长度
# request要求请求头是dict格式
headers = {
'Content-Length': len(data)
}
# urlopen 无法传递请求头
rsp = request.urlopen(baseurl, data=data)
json_data = rsp.read().decode("utf-8")
print(type(json_data))
print(json_data)
# 把json字符串转换为字典
json_data = json.loads(json_data)
print(type(json_data))
print(json_data)
for item in json_data['data']:
print(item['k'] + "---" + item['v'])
- 为了更多的设置请求信息,urlopen已经无法满足
- 需要利用request.Request 类
'''
利用parse模块模拟post请求
分析百度词典
步骤:
1. 打开F12
2. 尝试输入单词girl,发现每敲一个单词,都有一个请求
3. 请求地址是:http://fanyi.baidu.com/sug
4. 利用Network-All-Hearders-查看,发现fromdata的值是 kw:girl
5. 查看返回格式:是json格式,导入json包
'''
from urllib import parse, request
import json
'''
大致流程:
1. 利用data构造内容,然后urlopen打开
2. 返回一个json格式的结果
3. 结果就应该是girl的释义
'''
baseurl = 'http://fanyi.baidu.com/sug'
# 存放用来模拟fromdata的数据一定是dict格式
data = {
'kw': 'girl'
}
# 需要使用parse模块对data进行编码,最后编码为bytes流
data = parse.urlencode(data).encode("utf-8")
# 构造一个请求头,至少包含数据长度
# request要求请求头是dict格式
headers = {
'Content-Length': len(data)
}
# 构造一个Request类
req = request.Request(url=baseurl, data=data, headers=headers)
# 因为已经构造了一个Request实例,则所用的请求信息都可以封装在Request实例中
rsp = request.urlopen(req)
json_data = rsp.read().decode("utf-8")
# 把json字符串转换为字典
json_data = json.loads(json_data)
for item in json_data['data']:
print(item['k'] + "---" + item['v'])
- urllib.error
- URLError产生的原因:
- 没网
- 服务器连接失败
- 指不到服务器
- 是OSError的子类
- URLError产生的原因:
'''
URLError的使用
'''
from urllib import request, error
if __name__ == '__main__':
url = 'http://www.baiiiiiidu.com' # 网址错误,捕获错误
try:
req = request.Request(url=url)
rsp = request.urlopen(req)
html = rsp.read().decode()
print(html)
except error.URLError as e:
print("URLError:{0}".format(e.reason))
print("URLError:{0}".format(e))
except Exception as e:
print(e)
- HTTPError,是URLError的一个子类
'''
URLError的使用
'''
from urllib import request, error
if __name__ == '__main__':
url = 'http://www.sipo.gov.cn/www'
try:
req = request.Request(url=url)
rsp = request.urlopen(req)
html = rsp.read().decode()
print(html)
except error.HTTPError as e:
print("HTTPError:{0}".format(e.reason))
except error.URLError as e:
print("URLError:{0}".format(e.reason))
print("URLError:{0}".format(e))
except Exception as e:
print(e)
- 两者区别
- HTTPError是对应的HTTP请求的返回码错误,如果返回码在400以上,则引发HTTPError
- URLError对应的一般是网络出现问题,包括url问题
- 关系区别:OSError -> URLError -> HTTPError