利用 selenium webdriver 爬取网页的时候
若数据做了反爬 不好处理 就需要 模拟浏览器行为 -->操作dom-->获取数据 的方式。
前阵子做了一个百度 关键词库的爬虫脚本 有几点经验记录下来。方便以后直接用。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 30)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.new-fc-one-radio .new-fc-one-radio-input')))
等待xxx元素出现以后,在执行某些操作,如果大于30秒还没出来,抛出异常。
我这没有做try catch 因为像百度这种网站几乎不会有什么接口超时的问题。页面渲染很快的,EC有很多方法。一般情况用2种就够了。By 也有很多种,用于选择是那个元素 ,一般用css 或者 xpath都行!
# presence_of_all_elements_located 元素可加载出
# element_to_be_clickable 元素可点击
import time
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[value="otherBizPoint"]')))
driver.find_element_by_css_selector('input[value="otherBizPoint"]').click()
time.sleep(1.5)
driver.find_element_by_css_selector('.mock-input input').click()
time.sleep(0.5)
driver.find_elements_by_class_name('new-fc-one-menu-item-span')[0].click()
time.sleep(1)
allBoxItem =driver.find_elements_by_class_name('biz-point-item')
time.sleep(1.2)
睡眠是个很好用的方法,可以不用每次都显示判断,因为接口和dom渲染 怎么1秒也能搞定,为了防止find_element_by_css_selector 这样的方法报错,很有必要 加上sleep
其实根据你的需要 ,不一定要用前面2种,比如 一个 ul>il 只需要判断 这个li的 class 在页面中的length >0 就代表已经出现了
强烈建议用正则:如果用pyquery 或者 用 driver.find_elements_by_css_selector 这一类的方法,太麻烦了要过滤的东西太多了,在用 data=[] arr=[] for 去填充 就会很影响爬取时间 最快的方式,就是正则只需要做几步
print('获取数据中....')
html = driver.page_source
defalutVal = re.findall(
'.*?(.*?)(.*?)',
html,re.S)
print('获取完成....')
要先写出一个主流程、然后在主流程里 递归一个主方法。然后在考虑多线程的并行。这样一来,速度上去了,代码也不会很慢
。需要注意的是,全局变量和局部变量的区分。不要搞错了,如果不行还是 一个 主流程吧。。
写爬虫不能着急写,要先知道想要的是什么,一步步的实现步骤,先写出注释,然后在一个注释一个注释的填代码。根据每个网站的不同,代码不同,但是思路基本大同小异。只要先做到 前三条,不要报错找不到element,基本就很舒服了。