目录
前言
一、爬虫介绍
1.什么是爬虫?
2.爬虫的分类
3.爬虫的注意事项
二、requests模块
1.介绍
2.requests模块的编码流程
三、案例
1.爬取搜狗首页的页面数据
2.爬取搜狗指定词条对应的搜索结果页面
3.破解百度翻译
4.爬取豆瓣电影分类排行榜中的电影详情数据
5.爬取肯德基餐厅查询中指定地点的餐厅数据
6.爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据
从今天开始,博主将准别写15篇左右文章带领大家学习爬虫,爬虫其实并不难,坚持本博客的学习就可以上手做项目啦!
需要注意的是,建议大家熟练使用Google浏览器,并且学会查看后台源码和抓包程序,这是在学习爬虫中必不可少的过程,如果不会的话可以与我讨论!
本文主要介绍一些爬虫的基本概念,并教大家学会编写最简单的爬虫程序。由于篇幅受限,以总结经验为主,若有问题欢迎在评论区留言讨论!看过的小伙伴们别万关注+点赞+收藏呀!
通俗来说,爬虫就是通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。(模拟浏览器上网就是后面要说到的用User-Agent进行伪装)
当然有很多人都说学习爬虫就是从入门到入狱,爬虫本身并不违法,但是切忌用这门技术去干违法的事情。
- 通用爬虫: 抓取系统重要组成部分。抓取的是一整张页面数据。(本节要介绍)
- 聚焦爬虫: 是建立在通用爬虫的基础之上。抓取的是页面中特定的局部内容。
- 增量式爬虫: 检测网站中数据更新的情况。只会抓取网站中最新更新出来的数据。
①有些网站有反爬功能,要进行伪装才能进行爬取。
②robots.txt协议: 君子协议。规定了网站中哪些数据可以被爬虫爬取哪些数据不可以被爬取。
③常用请求头信息
- User-Agent:请求载体的身份标识
- Connection:请求完毕后,是断开连接还是保持连接
④常用响应头信息
- Content-Type:服务器响应回客户端的数据类型
我们在使用python爬虫时,需要模拟发起网络请求,主要用到的库有requests库和python内置的urllib库,urllib模块比较古老,操作繁琐并复杂,因此议使用requests,它是对urllib的再次封装,它们使用的主要区别:
requests可以直接构建常用的get和post请求并发起,urllib一般要先构建get或者post请求,然后再发起请求。
- 指定url
- User-Agent(UA)伪装
- 请求参数的处理
- 发起请求 (get或post请求)
- 获取响应数据
- 持久化存储(保存到excel或数据库)
下面我将用几个例子来演示requests模块中get和post请求爬取整个网页的过程。
这是最基础的爬虫,爬取的就是一个整体的静态html网页的源代码,响应一般都用response。
#- 需求:爬取搜狗首页的页面数据
import requests
if __name__ == "__main__":
#step_1:指定url
url = 'https://www.sogou.com/'
#step_2:发起请求
#get方法会返回一个响应对象
response = requests.get(url=url)
#step_3:获取响应数据.text返回的是字符串形式的响应数据
page_text = response.text
print(page_text) # 输出的就是该网页的源码
#step_4:持久化存储
with open('./sogou.html','w',encoding='utf-8') as fp:
fp.write(page_text)
print('爬取数据结束!!!')
①首先需要介绍一下UA:User-Agent(请求载体的身份标识)
-UA检测:门户网站的服务器会检测对应请求的载体身份标识,如果检测到请求的载体身份标识为某一款浏览器, 说明该请求是一个正常的请求。但是,如果检测到请求的载体身份标识不是基于某一款浏览器的,则表示该请求为不正常的请求(爬虫),则服务器端就很有可能拒绝该次请求。
-UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器。
-UA查找:可以通过查看浏览器后台找到自己的UA。
②ajax动态请求
本案例是一个ajax动态请求,ajax是一种浏览器通过js异步发起请求,局部更新页面的技术。ajax请求的局部更新,浏览器地址栏不会发生变化,局部更新不会舍弃原来页面的内容。
import requests
if __name__ == "__main__":
#UA伪装:将对应的User-Agent封装到一个字典中
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
url = 'https://www.sogou.com/web'
#处理url携带的参数:封装到字典中
kw = input('enter a word:')
param = {
'query':kw
}
#对指定的url发起的请求对应的url是携带参数的,并且请求过程中处理了参数
response = requests.get(url=url,params=param,headers=headers)
page_text = response.text
fileName = kw+'.html'
with open(fileName,'w',encoding='utf-8') as fp:
fp.write(page_text)
print(fileName,'保存成功!!!')
import requests
import json
if __name__ == "__main__":
#1.指定url
post_url = 'https://fanyi.baidu.com/sug'
#2.进行UA伪装
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
#3.post请求参数处理(同get请求一致)
word = input('enter a word:')
data = {
'kw':word
}
#4.请求发送
response = requests.post(url=post_url,data=data,headers=headers)
#5.获取响应数据:json()方法返回的是对象(如果确认响应数据是json类型的,才可以使用json())
dic_obj = response.json()
#持久化存储
fileName = word+'.json'
fp = open(fileName,'w',encoding='utf-8')
json.dump(dic_obj,fp=fp,ensure_ascii=False)
print('over!!!')
import requests
import json
if __name__ == "__main__":
url = 'https://movie.douban.com/j/chart/top_list'
param = {
'type': '24',
'interval_id': '100:90',
'action':'',
'start': '0',#从库中的第几部电影去取
'limit': '20',#一次取出的个数
}
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
response = requests.get(url=url,params=param,headers=headers)
list_data = response.json()
fp = open('./douban.json','w',encoding='utf-8')
json.dump(list_data,fp=fp,ensure_ascii=False)
print('over!!!')
拉到最底下,点击“餐厅查询”
import requests
if __name__ == '__main__':
post_url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
word = input('input a word:')
param ={
'cname': '',
'pid': '',
'keyword': word,
'pageIndex': '1',
'pageSize': '10',
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
response = requests.post(url=post_url, data=param, headers=headers)
data = response.text # 字符串类型 str
print(type(data))
print(data)
这个题是本节的综合性题目,有点难度,由于是笔记总结,不再叙述过多细节。
该题有些套娃的含义,因为它网页中并不是所有的信息都是静态显示的,所以爬取内容的时候要注意,是否存在ajax动态请求的网页。
而且如果想爬取若干页的信息,需要建立for循环。
import requests
import json
if __name__ == "__main__":
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'
}
id_list = [] # 存储企业的id
all_data_list = [] # 存储所有的企业详情数据
#批量获取不同企业的id值
url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsList'
#参数的封装
for page in range(1,6):
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']:
id_list.append(dic['ID'])
#获取企业详情数据
post_url = 'http://125.35.6.84:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in id_list:
data = {
'id':id
}
detail_json = requests.post(url=post_url,headers=headers,data=data).json()
# print(detail_json,'-------------ending-----------')
all_data_list.append(detail_json)
#持久化存储all_data_list
fp = open('./allData.json','w',encoding='utf-8')
json.dump(all_data_list,fp=fp,ensure_ascii=False)
print('over!!!')