爬虫和反爬虫的斗争
爬虫建议
- 尽量减少请求次数
- 保存获取到的HTML,供查错和重复使⽤
- 关注网站所有类型的页面
- H5页面
- APP
- 多伪装
- 代理IP
- 随机请求头
- 利用多线程分布式
- 在不被发现的情况下我们尽可能的提⾼速度
Ajax基本介绍
了解动态HTML技术
- JS
- 是⽹络上最常⽤的脚本语⾔,它可以收集⽤户的跟踪数据,不需要重载⻚⾯ 直接提交表单,在⻚⾯嵌⼊多媒体⽂件,甚⾄运⾏⽹⻚
- JQuery
- jQuery是⼀个快速、简洁的JavaScript框架,封装了JavaScript常⽤的功能代码
- ajax
- ajax可以使⽹⻚实现异步更新,可以在不重新加载整个⽹⻚的情况下,对⽹⻚的某部分进⾏更新
获取ajax数据的⽅式
1、直接分析ajax调⽤的接⼝。然后通过代码请求这个接⼝。
2、使⽤Selenium+chromedriver模拟浏览器⾏为获取数据
Selenium+chromedriver
Selenium 介绍
- selenium是⼀个web的⾃动化测试⼯具,最初是为⽹站⾃动化测试⽽开发 的,selenium可以直接运⾏在浏览器上,它⽀持所有主流的浏览器,可以接收指令,让浏览器⾃动加载⻚⾯,获取需要的数据,甚⾄⻚⾯截屏
- chromedriver是⼀个驱动Chrome浏览器的驱动程序,使⽤他才可以驱动浏览器。当然针对不同的浏览器有不同的driver。以下列出了不同浏览器及其对应的driver:
- 下载chromedriver
- 百度搜索:淘宝镜像(https://npm.taobao.org/)
- 安装总结:https://www.jianshu.com/p/a383e8970135
- 安装 Selenium :pip install selenium
- 将chromedriver放在环境变量path里。
Phantomjs快速⼊⻔
⽆头浏览器:⼀个完整的浏览器内核,包括js解析引擎,渲染引擎,请求处理等,但 是不包括显示和⽤户交互⻚⾯的浏览器
Phantomjs案例
# pip install selenium 换源安装
from selenium import webdriver
# 加载驱动
driver = webdriver.PhantomJS()
# 打开百度
driver.get('https://www.baidu.com/')
# 定位操作并输入内容通过send_keys()
driver.find_element_by_id('kw').send_keys('python') # 输入框
driver.find_element_by_id('su').click()
# print(driver.page_source) # 查看源码
print(driver.current_url) # 查看当前请求的url
# 截屏
driver.save_screenshot('baidu.png')
selenium快速入门
from selenium import webdriver
import time
driver = webdriver.Chrome()
# 打开百度
driver.get('https://www.baidu.com/')
# 窗口最大化
driver.maximize_window()
time.sleep(3)
# 关闭当前的窗口
driver.close()
time.sleep(1)
# 退出驱动关闭所有窗口
driver.quit()
定位元素
- find_element_by_id:根据id来查找某个元素
submitTag = driver.find_element_by_id('su')
submitTag1 = driver.find_element(By.ID,'su')
- find_element_by_class_name:根据类名查找元素
submitTag = driver.find_element_by_class_name('su')
submitTag1 = driver.find_element(By.CLASS_NAME,'su')
- find_element_by_name:根据name属性的值来查找元素
submitTag = driver.find_element_by_name('email')
submitTag1 = driver.find_element(By.NAME,'email')
-find_element_by_tag_name:根据标签名来查找元素
submitTag = driver.find_element_by_tag_name('div')
submitTag1 = driver.find_element(By.TAG_NAME,'div')
- find_element_by_xpath:根据xpath语法来获取元素
submitTag = driver.find_element_by_xpath('//div')
submitTag1 = driver.find_element(By.XPATH,'//div')
要注意, find_element 是获取第⼀个满⾜条件的元素。 find_elements 是获取所有满⾜条件的元素
操作表单元素
操作输⼊框:分为两步。
第⼀步:找到这个元素。
第⼆步:使⽤send_keys(value),将数据填充进去
- 使⽤clear⽅法可以清除输⼊框中的内容
inputTag.clear()
- 操作checkbox
因为要选中checkbox标签,在⽹⻚中是通过⿏标点击的。因此想要选中 checkbox标签,那么先选中这个标签,然后执⾏click事件
rememberTag = driver.find_element_by_name("rememberMe")
rememberTag.click()
- 操作按钮
操作按钮有很多种⽅式。⽐如单击、右击、双击等。这⾥讲⼀个最常⽤的。就 是点击。直接调⽤click函数就可以了
inputTag = driver.find_element_by_id('su')
inputTag.click()
- 选择select
select元素不能直接点击。因为点击后还需要选中元素。这时候selenium就专 ⻔为select标签提供了⼀个类selenium.webdriver.support.ui.Select。将获取 到的元素当成参数传到这个类中,创建这个对象。以后就可以使⽤这个对象进 ⾏选择了。https://www.17sucai.com/boards/53562.html
⾏为链
有时候在⻚⾯中的操作可能要有很多步,那么这时候可以使⽤⿏标⾏为链类 ActionChains来完成。⽐如现在要将⿏标移动到某个元素上并执⾏点击事件
actions = ActionChains(driver)
actions.move_to_element(inputTag)
actions.send_keys_to_element(inputTag,'python')
actions.move_to_element(submitTag)
actions.context_click()
actions.click(submitTag)
actions.perform()
还有更多的⿏标相关的操作
- click_and_hold(element):点击但不松开⿏标。
- context_click(element):右键点击。
- double_click(element):双击。
- 更多⽅法请参考:http://selenium-python.readthedocs.io/api.html
Cookie操作
- 获取所有的cookie
cookies = driver.get_cookies()
- 根据cookie的name获取cookie
value = driver.get_cookie(key)
- 删除某个cookie
driver.delete_cookie('key')
页面等待
现在的⽹⻚越来越多采⽤了 Ajax 技术,这样程序便不能确定何时某个元素完全 加载出来了。如果实际⻚⾯等待时间过⻓导致某个dom元素还没出来,但是你 的代码直接使⽤了这个WebElement,那么就会抛出NullPointer的异常。为了 解决这个问题。所以 Selenium 提供了两种等待⽅式:⼀种是隐式等待、⼀种 是显式等待
- 隐式等待:调⽤driver.implicitly_wait。那么在获取不可⽤的元素之前,会 先等待10秒中的时间
driver.implicitly_wait(10)
- 显式等待:显示等待是表明某个条件成⽴后才执⾏获取元素的操作。也可以 在等待的时候指定⼀个最⼤的时间,如果超过这个时间那么就抛出⼀个异 常。显示等待应该使⽤selenium.webdriver.support.excepted_conditions 期望的条件和selenium.webdriver.support.ui.WebDriverWait来配合完成
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 隐式等待
driver = webdriver.Chrome()
# driver.get('https://www.baidu.com/')
# driver.implicitly_wait(5)
# driver.find_element_by_id('fdfdfdfdf')
# 显示等待
driver.get('https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc')
# 出发地的条件
WebDriverWait(driver,100).until(
EC.text_to_be_present_in_element_value((By.ID,'fromStationText'),'长沙')
)
# 目的地的条件
WebDriverWait(driver,100).until(
EC.text_to_be_present_in_element_value((By.ID,'toStationText'),'北京')
)
# 定位查询按钮
btn = driver.find_element_by_id('query_ticket')
btn.click()
⼀些其他的等待条件
- presence_of_element_located:某个元素已经加载完毕了。
- presence_of_all_elements_located:⽹⻚中所有满⾜条件的元素都加载完毕了
- element_to_be_clickable:某个元素是可以点击了。
更多条件请参考:http://selenium-python.readthedocs.io/waits.html
打开多窗⼝和切换⻚⾯
- 有时候窗⼝中有很多⼦tab⻚⾯。这时候肯定是需要进⾏切换的。selenium 提供了⼀个叫做switch_to_window来进⾏切换,具体切换到哪个⻚⾯,可以 从driver.window_handles中找到
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# driver.get('https://www.douban.com/')
# 通过execute_script打开另外一个窗口 window.open()是js代码 execute_script可以操作js代码
driver.execute_script('window.open("https://www.douban.com/")')
time.sleep(3)
# driver.close() # 关闭当前的窗口
# driver.quit() # 退出驱动
# driver.find_element_by_id('kw').send_keys('python')
# 打印url地址
print(driver.current_url)
# 切换界面
# driver.switch_to_window() 过时了
# driver.switch_to.window()
driver.switch_to.window(driver.window_handles[1]) # driver.window_handles[1]切换网址
版权声明:本文为batyu1972原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。