一、爬虫认识
1、简介
爬虫:编写程序,模拟浏览器上网,然后抓去数据
价值:实际应用/就业
合法性: (1)、法律中不被禁止
(2) 、违法风险
(3)、善意爬虫/恶意爬虫
风险:干扰被访问网站正常运行/抓去受法律保护的特定信息
注意⚠️:优化程序,避免干扰网站正常运行
机密信息禁止爬去/传播
2、爬虫分类
-通用爬虫:
抓取系统重要组成部分。
抓取的是一整张页面数据。
-聚焦爬虫:
建立在通用爬虫的基础上。
抓取页面中特定的局部内容。
-增量式爬虫:
检测网站中数据更新情况。
只爬取网站中最新更新出来的数据。
3、反爬虫
爬虫矛与盾:
爬虫可以带来流量、收益;但不能别的竞争者抄袭,不被别人爬取信息
反爬机制:
门户网站通过制定相应的策略或技术手段,防止爬虫程序爬取信息
反反爬策略:
爬虫程序通过制定相关策略或技术手段,破解门户网站中具备的反爬机制,从而获取相关信息
4、robots.txt协议
君子协议。规定可爬取数据范围。(非强制性)
5、http协议(数据非加密)
- 概念:服务器与客户端进行数据交互的一种形式。
常用请求头信息
User- Agent:请求载体的身份标识(Google浏览器)
Connection:请求完毕后,是断开连接还是保持连接
常用响应头信息
Content-Type:服务器响应回客户端的数据类型
6、https协议(数据加密):
- 安全的超文本传输协议
- 加密方式(http://t.csdn.cn/pDq5L)
对称密钥加密:
非对称密钥加密:
证书密钥加密:
二、requests模块
1、介绍
Python requests 是一个常用的 HTTP 请求库,可以方便地向网站发送 HTTP 请求,并获取响应结果。
requests 模块比 urllib 模块更简洁。
使用 requests 发送 HTTP 请求需要先导入 requests 模块:
import requests
2、作用
模拟浏览器发起请求。
3、使用步骤
- 指定url
- 发起请求
- 获取响应的数据
- 持久化存储(获取到的数据)
4、模拟使用
- 爬取搜狗首页的页面数据
import requests
if __name__ == "__main__":
# 指定url(例如搜狗首页)
url = 'https://www.sogou.com/'
# get发起请求,返回一个响应对象
resp = requests.get(url=url)
# 获取响应的数据,.text返回字符串形式的相应对象
page_text = resp.text
print(page_text)
# 持久化存储page_text
with open('./sogou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
print("爬取结束!!")
- 爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
UA检测/UA伪装/url参数
import requests
# UA:User-Agent(请求身份标识)
# 反爬虫:UA检测--门户网站会检测请求载体身份标识(是否为爬虫)
# 反反爬虫:UA伪装--将请求载体标识伪装成某一浏览器
# 将对应的User-Agent封装到一个字典中
if __name__ == "__main__":
header = {
'User-Agent': 'Mozilla/5.0 。。。。。'# 代码不全
}
# 中文转化成乱码,可以换成中文
# url = 'https://www.sogou.com/web?query=%E8%8F%9C%E9%B8%9F%E6%95%99%E7%A8%8B'
url = 'https://www.sogou.com/web'
kw = input('enter a word :')
# query参数设置为动态
param = {
'query': kw
}
# 对指定的url发起的请求对应的url是携带参数的,并在请求过程中处理了参数
resp = requests.get(url=url, params=param, headers=header)
page_text = resp.text
fileName = kw + '.html'
with open(fileName, 'w', encoding='utf-8') as fp:
fp.write(page_text)
print(fileName, "保存成功")
UA:User-Agent(请求身份标识)
反爬虫:UA检测--门户网站会检测请求载体身份标识(是否为爬虫)
反反爬虫:UA伪装--将请求载体标识伪装成某一浏览器
将对应的User-Agent封装到一个字典中
- 破解百度翻译
- POST请求(携带参数例如“dog”)
- 响应数据是一组json数据
import requests
import json
if __name__ == "__main__":
# 这里的url是一个POST请求,非GET请求
post_url = 'https://fanyi.baidu.com/sug'
# UA伪装
header = {
'User-Agent': 'Mozilla/5.0 ....(未补全)
}
# post请求参数处理(同get请求一致)
word = input("enter a word:")
data = {
'kw': word
}
# 发送请求,返回json数据(也可直接.text)
resp = requests.post(url=post_url, data=data, headers=header)
# .json()方法返回的是obj对象(确认响应数据类型为json类型才可使用.json())
# 从调试窗口中的header中查看Content-Type返回类型
dic_obj = resp.json()
# 持久化存储
fileName = word+'.json'
fp = open(fileName, 'w', encoding='utf-8')
# ensure_ascii=False,有中文,即不能用ascii编码
json.dump(dic_obj, fp=fp, ensure_ascii=False)
print("爬取结束!!")
- 爬取豆瓣电影分类排行榜 http://movie.douban.com/中的电影详情数据
import requests
import json
if __name__ == "__main__":
url = 'https://movie.douban.com/j/chart/top_list'
param = {
# type = 24 & interval_id = 100 % 3A90 & action = & start = 0 & limit = 1
'type': '24',
'interval_id': '100:90',
'action': '',
'start': '0', # 从库中的第几部电影去取
'limit': '20' # 一次取几部电影
}
# UA伪装
header = {
'User-Agent': 'Mozilla/5.0 ......
}
reps = requests.get(url=url, params=param, headers=header)
# json格式数据
list_data = reps.json()
fp = open('./douban.json', 'w', encoding='utf-8')
json.dump(list_data, fp=fp, ensure_ascii=False)
print("爬取结束!!")
- 作业
爬取肯德基餐厅查询http:www.kfc.com.cn/kfccda/index.aspx中指定地点的餐厅数
局部信息爬取,输入城市后url不改变,但餐厅信息改变,以北京为例
import requests
import json
if __name__ == "__main__":
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
word = input("enter a word:")
param = {
'cname': '',
'pid': '',
'keyword': word,
'pageIndex': '',
'pageSize': '10'
}
# UA伪装
header = {
'User-Agent': 'Mozilla/5.0 '
}
list_data = [""]
for i in range(1, 11):
param['pageIndex'] = i
resp = requests.get(url=url, params=param, headers=header)
list_data.append(resp.json())
fileName = word + '.json'
fp = open(fileName, 'w', encoding='utf-8')
json.dump(list_data, fp=fp, ensure_ascii=False)
print("爬取结束!!")