爬虫之图片懒加载技术,selenium

 

一 . 图片懒加载技术

  案例分析:抓取站长素材http://sc.chinaz.com/中的图片数据

import requests from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) \
        Chrome/69.0.3497.100 Safari/537.36
', } #获取页面文本数据 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析页面数据(获取页面中的图片连接) #建立etree对象 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析获取图片地址和图片的名称 for div in div_list: image_url = div.xpath('.//img/@src') image_name = div.xpath('.//img/@alt') print(image_url) #打印图片连接 # print(image_name)#打印图片名称

  运行结果发现,咱们能够获取到图片名称,可是获取到的连接为空,这就是图片懒加载的缘由

  图片懒加载的概念:

图片懒加载是一种网页优化技术,当你请求网页的时候,若是全部图片一下全加载出来会影响网页加载效率的,
为了解决这个问题,先后端协同工做,使图片在浏览器当前窗口才加载出来,达到减小首屏图片请求次数,这种就称为图片懒加载

  网站通常实现图片懒加载的技术

在网页源码中,在img标签中首先会使用这个'伪属性'(一般使用src2,original...)去存放真正的连接,
当图片出现到可视化窗口的时候,会动态的替换成src属性,完成图片加载

  经过细致观察页面的结构后发现,网页中图片的连接是存储在了src2这个伪属性中

import requests from lxml import etree if __name__ == "__main__": url = 'http://sc.chinaz.com/tupian/gudianmeinvtupian.html' headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) \
        Chrome/69.0.3497.100 Safari/537.36
', } #获取页面文本数据 response = requests.get(url=url,headers=headers) response.encoding = 'utf-8' page_text = response.text #解析页面数据(获取页面中的图片连接) #建立etree对象 tree = etree.HTML(page_text) div_list = tree.xpath('//div[@id="container"]/div') #解析获取图片地址和图片的名称 for div in div_list: image_url = div.xpath('.//img/@src2') #src2伪属性 image_name = div.xpath('.//img/@alt') print(image_url) #打印图片连接 print(image_name)#打印图片名称

二 . selenium

  为何要使用selenium?

有些网站的数据是动态加载的,若是用requests是不能获取到数据的,用selenium经过驱动浏览器,彻底模拟浏览器操做,好比下拉,单击,跳转等,这样就能够获取到数据

  环境安装

下载安装selenium:pip install selenium 下载浏览器驱动程序: http://chromedriver.storage.googleapis.com/index.html 查看驱动和浏览器版本的映射关系: http://blog.csdn.net/huilan_same/article/details/51896672

  操做前须要知道的知识

# 元素定位
find_element_by_id() find_element_by_name() find_element_by_class_name() find_element_by_tag_name() find_element_by_link_text() find_element_by_partial_link_text() find_element_by_xpath() find_element_by_css_selector()

  简单使用与效果展现

from selenium import webdriver from time import sleep # 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
driver = webdriver.Chrome(r'驱动程序路径') # 用get打开百度页面
driver.get("http://www.baidu.com") # 查找页面的“设置”选项,并进行点击
driver.find_elements_by_link_text('设置')[0].click() sleep(2)  # 是为了看的更清楚 # 打开设置后找到“搜索设置”选项,设置为每页显示50条
driver.find_elements_by_link_text('搜索设置')[0].click() sleep(2) # 选中每页显示50条
m = driver.find_element_by_id('nr') sleep(2) m.find_element_by_xpath('//*[@id="nr"]/option[3]').click() m.find_element_by_xpath('.//option[3]').click() sleep(2) # 点击保存设置
driver.find_elements_by_class_name("prefpanelgo")[0].click() sleep(2) # 处理弹出的警告页面 肯定accept() 和 取消dismiss()
driver.switch_to_alert().accept() sleep(2) # 找到百度的输入框,并输入 美女
driver.find_element_by_id('kw').send_keys('美女') sleep(2) # 点击搜索按钮
driver.find_element_by_id('su').click() sleep(2) # 在打开的页面中找到“Selenium - 开源中国社区”,并打开这个页面
driver.find_elements_by_link_text('美女_百度图片')[0].click() sleep(3) # 关闭浏览器
driver.quit()

  上述的class和id都是经过网页源代码找到的

  -- 来一个有经常使用的功能简易版使用

from selenium import webdriver from time import sleep # 使用谷歌浏览器,填写浏览器驱动位置
driver = webdriver.Chrome(r'./chromedriver.exe') # 打开网址用get
bro = driver.get('http://www.baidu.com') sleep(2) # 找到搜索框的id
content_input = driver.find_element_by_id('kw') # 输入内容
content_input.send_keys('库里') sleep(2)
# 清空用clear() # content_input.clear()
#
找到搜索按钮的id btn = driver.find_element_by_id('su') btn.click() sleep(3) # 退出 driver.quit()

  执行js代码

from selenium import webdriver from time import sleep # 使用谷歌浏览器,填写浏览器驱动位置
driver = webdriver.Chrome(r'./chromedriver.exe') driver.get('https://xueqiu.com') sleep(3) # 实现滚轮向下滑动,第一个参数是横向滚轮,第二个参数是纵向
js = 'window.scrollTo(0,document.body.scrollHeight)'
# 执行js代码
driver.execute_script(js) sleep(2) # 每执行一次就向下滑动一下
driver.execute_script(js) sleep(2) # 这样就能获取到动态加载的数据了
print(driver.page_source) # 退出
driver.quit()

   谷歌无头浏览器,是一款无界面的谷歌浏览器

# 谷歌无头浏览器,不出现可视化界面
from selenium import webdriver from selenium.webdriver.chrome.options import Options from time import sleep # 建立一个参数对象,用来控制chrome以无界面模式打开
chrome_options = Options() chrome_options.add_argument('--headless') chrome_options.add_argument('--disable-gpu') # 使用谷歌浏览器,填写浏览器驱动位置
browser = webdriver.Chrome(executable_path=r'./chromedriver.exe', options=chrome_options) # 打开网址用get
bro = browser.get('http://www.baidu.com') sleep(2) # 找到搜索框的id
content_input = browser.find_element_by_id('kw') # 输入内容
content_input.send_keys('库里') sleep(2) # 找到搜索按钮的id
btn = browser.find_element_by_id('su') btn.click() sleep(3) # 截屏,没啥意义 # browser.save_screenshot('./curry.png')

# 退出
browser.quit()

  向前和后退

import time from selenium import webdriver browser=webdriver.Chrome(r'./chromedriver.exe') browser.get('https://www.baidu.com') browser.get('https://www.taobao.com') browser.get('http://www.sina.com.cn/') browser.back() time.sleep(2) browser.forward() time.sleep(2) browser.close()

  动做链(鼠标拖拽,键盘按键,这些动做的执行就是动做链)

from selenium import webdriver from selenium.webdriver import ActionChains import time browser = webdriver.Chrome() url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable' browser.get(url) # 当定位标签存在iframe的时候须要用到switch_to
browser.switch_to.frame('iframeResult')  # 里面是id # 初识位置
source = browser.find_element_by_id('#draggable') # 结束位置
target = browser.find_element_by_id('#droppable') # 建立一个动做链的对象
action = ActionChains(browser) action.drag_and_drop(source,target) # 执行动做链
aciton.perform() sleep(3) # 能够模拟人的拖动效果,慢慢的拖动 # 点击长按 # actions.click_and_hold(source) # time.sleep(3) # for i in range(5): # # perform表示开始执行动做链 # action.move_by_offset(xoffset=17,yoffset=0).perform() # time.sleep(0.5)
 browser.quit()

  selenium规避检测

如今很多大网站有对selenium采起了监测机制。好比正常状况下咱们用浏览器访问淘宝等网站的 window.navigator.webdriver的值为 undefined。
而使用selenium访问则该值为true。

  解决办法

from selenium.webdriver import Chrome from selenium.webdriver import ChromeOptions option = ChromeOptions() option.add_experimental_option('excludeSwitches', ['enable-automation']) driver = Chrome(r'浏览器驱动程序路径',options=option) # 其余操做不用变,再去console一下window.navigator.webdriver就显示undefined了
相关文章
相关标签/搜索