爬虫介绍
爬虫简介
通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。
爬虫分类
- 通用爬虫:要求爬取一整张页面源码数据
- 聚焦爬虫:要求爬取一张页面中的局部数据,聚焦爬虫一定是建立在通用爬虫基础之上。
- 增量爬虫:用来监测网站数据更新的情况,以便爬取到网站最新更新出来的数据。
- 分布式爬虫:提高爬取效率的终极武器。
反爬机制 --->是作用到门户网站中。如果网站不想让爬虫轻易爬取到数据,可以制定相关机制或者措施来阻止爬虫程序来爬取数据。
反反爬策略-->是作用在爬虫程序中。我们爬虫可以制定相关的策略来破解反爬机制从而爬取到相关的数据。
反爬机制:
- robots协议:一个纯文本的协议,协议中规定了该网站中哪些数据可以被哪些爬虫爬取,哪些不可以被爬取。访问:网站域名后面/robots.txt查看破解:防君子不防小人,可以不遵守该协议
- UA检测:网站后台会检测请求对应的User-Agent,以判定当前请求是否为异常请求。反反爬策略:UA伪装
- https(证书)使用的加密方式:证书里面包含(公钥)
requests模块
作用:基于网络请求的模块,可以模拟浏览器发请求。
下载安装:pip install requests
流程:
1、指定url
2、发起请求
3、获取响应数据
4、持久化存储
实例:
import requests # 1.指定url url = "https://www.sogou.com" # 2.发起请求,get会返回一个响应对象 response = requests.get(url=url) # 3.获取响应数据 page_text = response.text # text返回字符串形式的响应数据 print(page_text) # 4、持久化存储 with open("./sogou.html", "w", encoding="utf-8") as fp: fp.write(page_text)
参数动态化
若请求中携带了请求参数,则可以将请求参数封装到一个字典中,在params中携带即可;
UA监测:反爬机制
UA伪装:一种形式的反反爬策略
例如:
import requests # 出现了问题: # 1.乱码问题:解决需要将response响应进行:response.encoding = "utf-8" # 2.该网站有反爬策略:添加User-Agent请求头 word = input("请输入查询参数值:") # 参数动态化 url = "http://www.sogou.com/web" # url携带请求参数 params = { "query": word, } # UA伪装, headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", } # 注意需要携带参数进行请求发送 response = requests.get(url=url, params=params, headers=headers) # 修改响应数据的编码格式,要不然保存的html中会出现乱码 response.encoding = "utf-8" page_text = response.text fileName = word + ".html" with open(fileName, "w", encoding="utf-8") as fp: fp.write(page_text)
动态加载数据的捕获
需要的数据通过ajax发送请求获得。
例子:需求:获取豆瓣电影分类排行-悬疑片的title和score评分
import requests # 需求:获取豆瓣电影分类排行-悬疑片的title和score评分 params = { "type": "10", "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/85.0.4183.83 Safari/537.36", } url = "https://movie.douban.com/j/chart/top_list" movie_data = requests.get(url=url, params=params, headers=headers).json() for dic in movie_data: name = dic.get("title") score = dic.get("score") print(name, score)
药监局
# 分析:发现企业详情数据是动态加载,通过全局搜索找到动态加载对应的数据表,从该数据表中提取出: # 1.url 2.请求方式 3.携带请求参数(id,不同企业对应的id值是不同) # 结论:如果可以将每一家企业的id数据获取,则就可以批量爬取到每一个企业对应的详情数据。 # 获取每一个企业的id # 获取前5页的企业名称和法人姓名 import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36", } for page in range(1, 6): url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsList" data = { 'on': 'true', 'page': str(page), 'pageSize': '15', 'productName': '', 'conditionType': '1', 'applyname': '', 'applysn': '', } rest_data = requests.post(url, headers=headers, data=data).json() for dic in rest_data.get("list"): _id = dic.get("ID") # 基于ID获取每一家企业信息 url = "http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById" data = { "id": _id, } company_info = requests.post(url, headers=headers, data=data).json() # 企业名称和法人姓名 print(company_info.get("epsAddress"), company_info.get("legalPerson"))