目录
一,爬虫简介
一句话,干脆利落。
网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。
抓取完信息,你可以做很多事情。
爬虫分类
根据使用场景,网络爬虫可分为通用爬虫和聚焦爬虫两种。
二,Requests 模块 get 请求
(一)Requests 模块
1、requests 库简介
Urllib 和 Requests 模块是发起 http 请求最常见的模块。 虽然 Python 的标准库中 urllib 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “httpforHumans”,说明使用更简洁方便。
Requests 继承了 urllib 的所有特性。Requests 支持 http 连接保持和连接池,支持使用 cookie 保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。
requests 的底层实现其实就是 urllib3(urllib2 的升级版—python2 支持) Requests 的文档非常完备,中文文档也相当不错。 Requests 能完全满足当前网络的需求,
支持 Python2.6—3.6. 开源地址:git地址
中文文档 API地址
2、安装方式
利用 pip 安装 或者利用 easy_install 都可以完成安装: $pip installrequests
(二)网络请求
客户端发送请求主要有两种请求方法—get和post。
get请求主要是从服务器去获取内容, 大多数的请求都是 get 请求,post 请求是向服务器提交一些内容,比如表单等。
1,最基本的 POST 请求使用方法:
#(1)导入 requests 模块
import requests
#(2)发送请求,获取响应
response = requests.get(
url= "请求 url 地址",
headers= "请求头字典",
params= "请求参数字典",
)
2,response 对象的属性
1、字符串响应内容
response.text
当我们使用 response.text 来获取页面内容的时候,Requests 会自动解码来自服务器的内 容,response.text 获取的是页面字符串内容。
2、二进制响应内容
response.content
3、json 响应内容
7
Requests 中也有一个内置的 JSON 解码器,助你处理 JSON 数据。
如果 JSON 解码 失败, response.json() 就会抛出一个异常。
例如,响应内容是 401(Unauthorized),尝试访 问 response.json() 将会抛出 ValueError:NoJSON objectcouldbedecoded 异常。
4、响应状态码
response.status_code
200:正常
404:未找到地址
403:权限不够
500:代码错误
5、响应头
response.headers
6、页面内容乱码问题
(1)设置正确的编码方式
设置方法是给 response.encoding 设置一个正确的编码,requests 模块会自动根据设置的 编码来将服务器相应的内容按照这个编码成字符串,这时候我们通过 response.text 字段就可 以获取正确的页面内容了。
response.encoding = 'utf-8'
# print(response.encoding)
response_str = response.text
# print(response_str)
(2)通过 response.content.decode(‘正确的编码’)方法
来将二进制内容按照提供的编码方式 编码成 unicode 字符串,进而正确显示。
案例
1. 爬取百度产品网页
#1、导包
import requests
#2、发送请求,获取响应
response = requests.get(url='https://www.baidu.com/more/')
"""
响应正文两种类型:
字符串类型
解决乱码:编解码不一致
自动确定的编码就是response.encoding
第一种解决乱码问题的方法:正确的编码赋值给response.encoding,在使用response.text获取、
"""
response.encoding = 'utf-8'
# print(response.encoding)
response_str = response.text
# print(response_str)
html = str(response.content,encoding='utf-8')
with open('index.html','w',encoding='utf-8') as fp:
fp.write(response_str)
2. 爬取新浪新闻网页
请求的是:http://search.sina.com.cn/?q=A%E8%82%A1&c=news&from=channel&ie=utf-8
请求方式是:get 请求。
携带的参数是:有四个,其中一个参数是中文,请求的时候需要编码。
import requests
def get_news1(kw):
"""
通过requests模块params参数来进行带参数的get请求
:param kw:
:return:
"""
# 发送请求,获取响应
# 带参数的get请求他的url可以分为两部分:
# https://search.sina.com.cn/?---基础url----写到url参数里面
# q=python%E7%88%AC%E8%99%AB&range=all&c=news&sort=time-=--参数
# 请求参数字典
params = {
'q': kw,
'range': 'all',
'c': 'news',
'sort': 'time',
}
response = requests.get(url='https://search.sina.com.cn/?', params=params)
# print(response.text)#大多数情况下,response.text自动识别编码功能是不会出现乱码
with open('sina_news.html', 'w', encoding='utf-8') as fp:
fp.write(response.text)
def get_news2(kw):
"""
通过格式化字符串的形式进行请求
:param kw:
:return:
"""
base_url = 'https://search.sina.com.cn/?q=%s&range=all&c=news&sort=time' %kw
print(base_url)
#requests模块在请求时,自动会将url中的中文进行url编码
response = requests.get(base_url)
with open('sina_news2.html', 'w', encoding='utf-8') as fp:
fp.write(response.text)
if __name__ == '__main__':
kw = input('请输入新闻关键字:')
get_news1(kw)
# get_news2(kw)
3. 爬取百度贴吧
首先我们创建一个 python 文件,我们要完成的是,输入一个百度贴吧的地址,比如: 百度贴吧 LOL 吧,
第一页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0
第二页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50
第三页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100
发现规律了吧,贴吧中每个页面不同之处,就是 url 最后的 pn 的值,其余的都是一样 的,我们可以抓住这个规律。
现在简单写一个小爬虫程序,来爬取百度 LOL 吧的所有网页。
import requests, os
'''
增加一个分页需求:实现爬取多页
一般情况下:分页都是通过带参数的get请求中一个参数控制的,只需要找到规律即可。
1:0
第二页:pn=50
3 :pn=100
4:pn=150
'''
def get_page1(kw,pn,filename):
"""
获取pn页的kw爬的数据
:param kw: 贴吧名称
:param pn: 页码
:filename:文件名
:return:
"""
base_url = 'https://tieba.baidu.com/f?'
# 发送请求获取响应
params = {
'ie': 'utf-8',
'kw': kw,
'pn': pn,
}
response = requests.get(base_url, params=params)
with open(filename, 'w', encoding='utf-8') as fp:
fp.write(response.text)
if __name__ == '__main__':
kw = input('请输入贴吧的名称:')
for i in range(10):
pn = i*50
#自动创建文件夹
filename = r'./tieba/'+kw
if not os.path.exists(filename):
os.mkdir(filename)
get_page1(kw,pn,filename+'/{}.html'.format(i+1))
4. 爬取百度页面
import requests
#发送请求获取响应
#问题:发现响应内容比较少。
#请求头:请求的详细信息。--一旦请求出问题了,基本上就是请求头没有封装或者封装有问题。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
}
response = requests.get(url='https://www.baidu.com/',headers = headers)
print(response.content.decode('utf-8'))
三,Requests 模块 post 请求
(一)网络请求
1. 最基本的 POST 请求使用方法:
#(1)导入 requests 模块
import requests
#(2)发送请求,获取响应
response = requests.post(
url= "请求 url 地址",
headers= "请求头字典",
data= "请求参数字典",
)
案例
5. 重写百度翻译
import requests
"""
开发的流程:
#1、细化需求,取逐步突破
#2、将每个功能扩展我每个方法或者多个类。
#3、创建一个中间调度引擎,进行解耦组合。
"""
def trans_word(word):
# 发送请求,获取响应细化步骤:
# 1、确定基础url
base_url = 'https://fanyi.baidu.com/sug'
# 2、确定请求头字典
# post请求中比较重要的请求头
# content-length: 7-----提交表单数据的长度
# content-type: application/x-www-form-urlencoded; charset=UTF-8-----提交表单数据的格式
# x-requested-with: XMLHttpRequest---ajax请求必须要分装的请求头
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',
'x-requested-with': 'XMLHttpRequest',
'content-length': str(len(word)+3),
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
}
# 3、确定data字典
data = {
'kw': word,
}
response = requests.post(base_url, data=data, headers=headers)
# print(response.text)#json数据----用于网络传输
# #requests自动解析json方法
# print(response.json()) # 返回的就是pythonlist或者字典
json_data = response.json()
# print(type(json_data))
result = ''
for data in json_data['data']:
# print(data)
result += data['v'] + '\n'
print(result)
if __name__ == '__main__':
word = input('请输入单词:')
trans_word(word)