python爬虫笔记
爬虫一些概念
- 什么是爬虫?
通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。 - 爬虫在使用场景中的分类:
(1)通用爬虫:抓取系统重要组成部分。抓取的是一整张页面数据
(2)聚焦爬虫:建立在通用爬虫的基础之上。抓取的页面中特定的局部内容。
(3)增量式爬虫:检测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。 - 爬虫的矛与盾:
(1)反爬机制:门户网站,可以通过制定相应的策略或技术手段,防止爬虫程序进行网站数据的爬取。
(2)反反爬策略:爬虫程序可以通过制定的相应的策略或技术手段,破解门户网站中具备的反爬机制,从而获取相应的信息。 - robots.txt协议:
君子协议。规定了网站中那些数据可以爬取那些数据不可以被爬取。
爬虫基础
- http协议
概念:服务器和客户端进行数据交互的一种形式。 - 常用请求头信息
User-Agent :请求载体的身份标识。
connection:请求完毕后,是断开连接还是保持连接 - 常用响应头信息
content -type:服务器响应回客户端的数据类型 - https协议
安全的http(超文本传输)协议,其中包含数据加密 - 加密方式:
(1)对称秘钥加密 :客户端将加密的数据以及密钥一起发给服务器 存在安全隐患
(2)非对称密钥加密 :服务器将数据加密方式发给客户端,客户端利用收到的密钥(公钥)进行加密,将加密好的数据发给服务器端,服务器自行解密(私钥)。 效率低,不能保证服务器公钥的正确性。
(3)证书密钥加密
服务器端制定公钥,将公钥提供给证书认证机构,证书认证机构给公钥数字签名,并提供给客户端,之后再将加密好的发给服务器端,服务器用私钥进行解密。
爬虫代码基础
- requests模块
-urllib模块
-requests 模块
requests 模块:python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率及高。
作用:模拟浏览器发请求。
如何使用:(requests模块的编码流程)
-指定url(网址)
-UA伪装
-请求参数的处理
-发起请求
-获取响应数据
-持久化存储
环境安装:
pip install requests
实战编码:
-需求:爬取搜狗首页的页面数据
import requests
if __name__ == '__main__':
#1.指定url
url = 'https://www.sogou.com/'
#2.发起请求
#get方法会返回一个相应对象
response = requests.get(url = url)
#3.获取相应对象,text返回的是字符串式的相应数据
page_text = response.text
print(page_text)
#4.持久化存储
with open('./sogou.html','w',encoding = 'utf-8') as fp:
fp.write(page_text)
print('爬取数据结束')
- 实战巩固
-需求:爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
-UA检测
-UA伪装
-需求:破解百度翻译
-post请求(携带了参数)
-响应数据是一组json数据
-需求:爬取豆瓣电影分类排行榜 https://movie.douban.com 中的电影详情
-需求:爬取肯德基餐厅查询位置信息
-需求:爬取药监局监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
-动态加载数据
-首页中对应的企业信息数据是通过ajax动态请求到的。
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=ff83aff95c5541cdab5ca6e847514f88
http://scxk.nmpa.gov.cn:81/xk/itownet/portal/dzpz.jsp?id=2c6260fb9c57420b85e94c885b589972
-通过对详情页url的观察发现:
-url的域名都是一样的,只有携带的参数(id)不一样
-id值可以从首页对应的ajax请求道的json串中获得
-域名和id值拼接出一个完整的企业对应的详情页的url
-详情页的企业详情数据也是动态加载出来的
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById
-观察后发现:
-所有的post请求的url都是一样的,只有参数id不同
-如果我们可以批量获取多家企业的id后,就可以将id和url形成一个完整的详情页对应详情数据的ajax请求的url。
(1)简易网页采集器
抓包工具使用:打开一个浏览器,右键空白区域,检察元素,即可打开抓包工具。
import requests
if __name__ == '__main__':
header = {
'User-Agent':'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
}
url = 'https://www.baidu.com/s'
#处理url携带的参数:封装到字典中
kd = input('搜索内容:')
param = {
'wd' : kd
}
#对指定的url发起的请求对应的url是携带参数的
response = requests.get(url = url ,params = param ,headers = header)
page_text = response.text
fileName = kd + '.html'
with open('F:/python_test/requests_test/' + fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName,'保存成功')
(2)破解百度翻译
import requests
import json
if __name__ == '__main__':
#指定url
post_url = 'https://fanyi.baidu.com/sug'
#post请求参数处理(同get请求一致)
word = input('输入要翻译的单词:')
data = {
'kw': word
}
#进行UA伪装
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
}
#请求发送
response = requests.post(url = post_url,data = data,headers = headers)
#获取响应数据 json方法返回的是obj(如果确认服务器返回的响应数据是json类型的数据,才可以使用json方法返回对象,在响应头里看content-type,而不是在返回响应里看)
dic_obj = response.json()
#进行持久化存储
Filename = word + '.json'
fp = open('F:/python_test/requests_test/' + Filename,'w',encoding='utf-8')
json.dump(dic_obj,fp=fp,ensure_ascii = False)#ensure_ascii = False保证是中文,不是ASCII编码
print('over')
(3)爬取肯德基餐厅查询位置信息
当点击查询按钮后,浏览器上方网址不变,说明当前请求是一个阿贾克斯请求,在抓包工具中找到相应参数值,按照第二个案例进行程序修改相应参数,即可实现相应功能。
(4)爬取药监局监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
尝试1:直接抓取http://scxk.nmpa.gov.cn:81/xk/网页信息
import requests
import json
if __name__ == '__main__':
url = 'http://scxk.nmpa.gov.cn:81/xk/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
}
page_text = requests.get(url = url,headers = headers).text
with open ('F:/python_test/requests_test/drug.html','w',encoding='utf-8') as fp:
fp.write(page_text)
结果:抓取页面没有各个化妆品开发商
原因:我们利用浏览器搜索到的数据并不是通过当前url网址请求到的,而是通过其他阿贾克斯请求请求到的。也叫动态加载出来的数据。
实现代码:
import requests
import json
if __name__ == '__main__':
#批量获取不同企业的id值
url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0'
}
#参数的封装
id_list = []#存储企业的id
all_data_list = []#存储所有企业的详情数据
for page in range(1,3):
page = str(page)
data = {
"on":"true",
"page":page,
"pageSize":"15",
"productName":"",
"conditionType":"1",
"applyname":"",
"applysn":""
}
json_ids = requests.post(url = url,headers = headers,data = data).json()
for dic in json_ids['list']: # json_ids['list']是一个列表 dic是一个字典
id_list.append(dic['ID'])
#print(id_list)#可以直接打印整个列表
#获取企业详情数据
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in id_list:
data = {
'id': id
}
detail_json = requests.post(url= post_url,data = data,headers=headers).json() #detail_json是一个字典
#print(detail_json,'----------------ending-------------------')
all_data_list.append(detail_json)
#持久化存储
fp = open('F:/python_test/requests_test/drug_2.json','w',encoding='utf-8')
json.dump(all_data_list,fp=fp,ensure_ascii=False,indent=True)#indent=True自动排版
print('over')