反爬策略
-
1. 判断user-agent客户端标识来判断是否为爬虫
- 解决办法:封装 user-agent 到请求头
-
2. 通过访问频率来判断
解决办法:- 设置等待时长,爬取时间间隔,可以使用强制等待。
- 在用户高峰期爬取,冲散日志
-
3. 封 IP
- 解决办法:使用代理池
-
4. 页面的内容无法直接获取,都是js 代码
- 解决办法:selenium + phantomjs 的组合进行页面内容的获取
-
5. ajax 异步请求
- 解决办法:用接口获取数据
-
6. 能一次性获取的数据,绝不发送第二次请求(获取数据的过程中尽量减少请求次数)
html页面的技术
js
页面在请求 html 的过程中,服务器返回 html ,同时还会请求js 文件
jqery
是一个 js 库,可以简化 js 代码
ajax
web 的异步请求
DHTML
动态的html (标准通用标记语言下的一个应用),是相对传统的静态的 html 而言的一种制作网页的概念
selenium + phantomjs
什么是selenium
selenium 是一个自动化测试工具。(但是本身不带浏览器)这个工具其实是作为外部工具驱动来使用的,可以控制一些外部应用来完成自动化测试
什么是phantomjs
其实是一个内置无界面浏览器引擎,无界面可以提高程序运行速度
因为phantomjs 是一个浏览器引擎,所以他最最大的功能就是执行页面的 js 代码
安装
- selenium 安装:
pip install selenium==2.48.0 - phantomjs 安装:百度phantomjs 镜像,下载windows版本的
- 将下载好的 phantomjs.exe 文件放在<Anaconda\Scripts>目录下
- 安装 Chromedriver(可视化的Chrome浏览器插件)
- 百度 Chromedriver 镜像
- 查看自己的Chrome版本号
- 找一个和自己浏览器版本号最接近的版本下载
- 将下载好的 Chromedriver.exe 文件放在<Anaconda\Scripts>目录下
selenium + Chrome 的使用
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
# 1.创建一个浏览器驱动
driver = webdriver.Chrome()
# 2.请求url
driver.get('http://www.baidu.com/')
# 查看标题
print(driver.title)
# 查看cookies
print(driver.get_cookies())
# 查找标签元素
driver.find_element_by_id('kw').send_keys()
# webelement对象
webEle = driver.find_element_by_id('kw')
input = driver.find_element_by_id('kw')
input.send_keys('蔡徐坤') # 寻找百度搜索框,并写入Unicode编码的蔡徐坤
submit = driver.find_element_by_id('su')
submit.click() # 寻找搜索框的确定按钮点击
driver.save_screenshot('cxk1.jpg') # 截屏
print(driver.current_url)#当前url
print(driver.name)#查看浏览器名字
# 将某个输入框的输入东西删除
input.send_keys(Keys.CONTROL, 'a') # 全选
input.send_keys(Keys.CONTROL, 'x') # 剪切
# 查看input元素的坐标
input.send_keys('周杰伦')
print(input.location)#{'x': 129, 'y': 18}
# #查看元素大小
print(input.size)#{'height': 22, 'width': 395}
#常用的查找element对象的方法
driver.find_element_by_id('kw')
driver.find_element_by_css_selector('#kw').send_keys('aa')#css选择器
driver.find_element_by_xpath()
selenium + phantomjs 请求页面
- 导包
driver = webdriver.Chrome()
- 创建driver对象
driver = webdriver.Chrome()
- 三种等待
-
强制等待:不管页面是否加载胡来,强制让进程等待
time.sleep(2) -
隐式等待:等待页面全部加载完成
driver.implicitly_wait(20)弊端:页面的加载其实不单单是页面html,重要还有一些页面静态资源,而静态资源的加载是最耗时。这些静态资源对我们爬取数据又没什么作用,所以隐式等待其实效率并不高。
-
显示等待:满足一些内置的等待条件,只要这些条件满足,等待结束。
-
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
#1.创建等待对象
wait = WebDriverWait(
driver,#浏览器驱动对象
10,最大等待时长
0.5,扫描间隔
)
#2.wait.until(等待条件)--->等待条件成立程序才继续运行。
#等待条件在selenium中有个专门的模块来设置了一些条件--expected_conditions as EC
#最常用的条件有一下两个:这两个条件验证元素是否出现,传入的参数都是元组类型的locator,如(By.ID, 'kw')
EC.presence_of_element_located#一个只要一个符合条件的元素加载出来就通过;
EC.presence_of_all_elements_located# 另一个必须所有符合条件的元素都加载出来才行
EC.presence_of_element_located(locator对象也就是定位器)
licator对象是一个元组(通过什么来查找,--By.ID,By.XPATH,By.CSS_SELECTOR‘查找的内容的语法’)
#3.wait.until方法的返回值是一个对应定位器所定位到的webelement对象。你如果需要对这个webelment对象做一些点击或者其他操作,可以很方便的做到。
#4获取页面内容
html = driver.page_source
#5.用lxml模块解析页面内容
tree = etree.HTML(html)
本文探讨了常见的反爬虫策略,包括通过User-Agent、访问频率、封IP、页面JS内容、AJAX请求等手段识别爬虫,并提供了相应的解决办法,如使用代理池、selenium+phantomjs组合、合理设置请求间隔等。

716

被折叠的 条评论
为什么被折叠?



