### 动态 HTML 处理 #### 爬虫与反爬虫 + 爬虫的建议 1. 尽量减少请求次数,能抓列表页就不抓详情页,减轻服务器压力,不要只看 Web 网站,还有手机 App 和 H5, 反爬措施会少一点 2. 对性能要求比较高的时候,需要考虑多线程、分布式 + **反爬策略** 1. 通过**user-agent来判断**是否是爬虫. + 解决办法: 1. **封装user-agent**。 2. **准备user-agent池** 2. **封ip**:是网站针对爬虫最终策略。 + 解决办法:使用**代理ip**---代理池项目 3. 通过**请求的频率**来限制爬取。 + 解决办法: 1. 设置**请求头频率**限。time.sleep(0.1-0.9) 2. **减少请求次数**:能在列表页获取,就不再详情页。但是要记得保存详情页url。能一次获取,就不多次获取。(ajax请求。limit:50) 4. **验证码**:**破解验证码** 5. 数据不是直接渲染到html页面中,而是通过**js异步获取数据**。 + 解决办法: 1. 使用**内置浏览器引擎**的爬虫(selenium+chrome/phantomjs) #### Ajax 数据获取 ##### Ajax 介绍 + Ajax 技术 : 表单提交后,从服务器获取信息之后,网站的页面不需要重新刷新 + Ajax 不是一门语言,是用来完成网络任务 的一系列技术.Ajax 全称 (Asynchronous JavaScript and XML : 异步 JavaScript 和 XML), 网站不需要使用单独的页面请求就可以和网络服务器进行交互 (收发信息) + Ajax 是一种客户端技术, 当浏览器通过一些 JavaScript 动作 (页面滑动、点击按钮等),此时 Ajax 引擎发送 HTTP 请求,服务器返回数据给 Ajax 引擎,最后 Ajax 引擎将服务器返回的数据渲染到浏览器当前的页面中,不需要对整个页面进行刷新就能加载数据 + 爬取 Ajax 请求数据时,可以直接获取 HTTP 请求接口,从此接口获取数据,大大提升爬虫爬取效率 ##### Ajax请求分析 + Ajax 请求 位于浏览器 开发者模式中 Network 的 XHR (XmlHttpRequest) 对象中 + Ajax 请求分析步骤 1. **分析请求** : 找到页面中的 Ajax 请求 对于网页`F12 --> NetWork --> XML --> 查看发送与响应` 2. **分析响应** : 找到 Ajax 请求并确认具体哪条获得页面数据的 Ajax 请求 + 对于Ajax 请求,点开具体链接,分析该请求的详细信息,**response**、**preview** + 如果响应内容中包含页面数据,那么该请求就是需要获取请求 3. **解析响应内容** : 一般 Ajax 请求都是 JSON 数据,解析 JSON 数据即可 #### Selenium 数据获取 ##### Selenium 简介 + Selenium : **Web 自动化测试工具**,可以按照指定的命令自动操作,Selenium 可以直接运行在浏览器上,支持所有主流浏览器 (包括 PhantomJS 等无界面浏览器) + Selenium 可以根据我们的指令,让浏览器自动加载界面,获取需要的数据,网页截屏,判断网站发生的动作 + Selenium不自带浏览器,需要与第三方浏览器结合才可使用,使用方法 1. 使用 PhantomJS 工具代替真实浏览器 2. 下载火狐浏览器的 `geckodriver` [下载链接](https://github.com/mozilla/geckodriver/releases) 或 谷歌浏览器的 `chromedriver` (与浏览器版本对应, chromedriver 下载链接构造 **https://chromedriver.storage.googleapis.com/index.html?path=谷歌浏览器版本/**) 1. 火狐浏览器不弹出页面 ```python from selenium.webdriver.firefox.options import Options options = Options() options.headless = True driver = webdriver.Firefox(firefox_options=options, executable_path=ex_path) ``` 2. 谷歌浏览器不弹出界面 ```python from selenium import webdriver from selenium.webdriver.chrome.options import Options from PIL import Image,ImageEnhance path = 'C:/dd/chromedriver.exe' # chromedriver.exe 驱动的路径 #打开浏览器 chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') # 创建浏览器对象 driver = webdriver.Chrome(executable_path=path, chrome_options=chrome_options) ``` + Selenium 常用方法: 1. `driver = webdriver.Chrome(executable_path=executable_path)` : 创建 driver 对象 **executable_path** 表示浏览器 chromedriver 地址 1. `driver.get(url)` : 打开指定 url 界面 2. `driver.quit()` : 关闭 打开页面 3. `driver.page_source` : 获取页面源码 (加载过 AJAX 等请求后的页面源码) 4. `driver.maximize_window()` : 打开窗口最大化 5. `driver.save_screenshot('go.png')` : 页面截屏,截取全屏 2. 模拟按键操作 1. 导入 **Keys** 方法 : `from selenium.webdriver.common.keys import Keys` 2. 获取操作对象的标签 : `input_label = driver.find_element_by_id('kw')` 3. 对操作对象传参或者按键操作 1. 传参 : `input_label.send_keys("python")` 2. 按键操作 : + 单个按键 : `input_label.send_keys(Keys.ENTER)` (回车键) + 组合按键 : `input_label.send_keys(Keys.CONTROL, "x")` (Ctrl+X) 3. 获取操作对象的左顶点位置 (返回 x, y 坐标字典数据) : `input_label.location` 4. 获取操作对象的尺寸 (返回 height 和 weight 字典数据) : `input_label.size` + Selenium 操作的重点在于 确定等待时间 以提高效率 1. 强制等待 : `import time` ```python import time time.sleep(3) ``` 2. 隐式等待 : `driver.implicitly_wait(wait_time)` + 页面全部加载结束开始运行,指定最大等待时长,超出等待时长或等待时长内加载失败报一个异常 + 等待加载包括页面广告、静态 JS 等无用信息, + 遇到页面异步加载不能使用 3. 显式等待 (WebDriverWait) : 等待页面特定元素 (使用元素定位器定位) 满足特定条件 (定位器和特定查询条件) 开始加载 1. 导入 定位器、查询条件、显式等待所用方法 ```python from selenium.webdriver.common.by import By # 定位器 from selenium.webdriver.support import expected_conditions as EC # 查询条件 from selenium.webdriver.support.wait import WebDriverWait # 显式等待 ``` 2. 创建显式等待对象 ```python wait = WebDriverWait(driver, 20) ``` 3. 使用定位器 根据 查询条件 确定加载等待用时 + `EC.presence_of_element_located(查询方法, 定位语句)` : 定位单个元素 + `EC.presence_of_all_elements_located(查询方法, 定位语句)` : 定位多个元素 + 实例 ```python wait.until(EC.presence_of_all_elements_located(By.XPATH, '等待位置的 XPATH 语句')) # 等到元素出现为止,传入定位器 ``` ##### PhantomJS 简介 + PhantomJs : 基于 Webkit 的 "无界面" (headless) 浏览器,会把网站加载到内存并执行页面上的 JavaScript,由于不展示图形界面,所以使用效率更高 + PhantomJS 只能从官网[下载](https://phantomjs.org/download.html),pahntomJS 是一个功能完善的浏览器 ##### JS 简介 + 判断 PhantomJS 安装成功: 1. 设置环境变量后,打开 cmd ,直接输入 `phantomjs` 成功运行则安装成功 2. `driver = webdriver.PhantomJS(executable_path='phantomjs-2.1.1-windows\bin\phantomjs.exe')`