0


爬虫 | Selenium库

一.基础

1.定义

  • 自动化测试工具,支持多种浏览器。爬虫中主要用来解决JavaScript渲染的问题
  • 便捷地获取网站中动态加载的数据
  • 便捷实现模拟登录

2.使用流程

  • 环境安装:pip install selenium
  • 下载一个浏览器的驱动程序
  • 实例化一个浏览器对象:bro = webdriver.Chrome(executable_path='./chromedriver')
  • 编写基于浏览器自动化的操作代码

二.常用操作

1.元素定位

获取单个元素

driver.find_element(By.ID,"inputOriginal")
driver.find_element(By.CSS_SELECTOR,"#inputOriginal")
driver.find_element(By.TAG_NAME,"div")
driver.find_element(By.NAME,"username")
driver.find_element(By.LINK_TEXT,"下一页")

获取多个元素

driver.find_elements(By.ID,"inputOriginal")
driver.find_elements(By.CSS_SELECTOR,"#inputOriginal")
driver.find_elements(By.TAG_NAME,"div")
driver.find_elements(By.NAME,"username")
driver.find_elements(By.LINK_TEXT,"下一页")

2.内容获取

  • size:返回元素大小
  • text:获取元素的文本
  • title:获取页面title
  • current_url:获取当前页面url
  • get_attribute:获取属性值
  • is_display():判断元素是否可见
  • is_enabled():判断元素是否可用
driver = webdriver.Chrome("./chromedriver.exe")
#加载有道翻译页面
driver.get("https://fanyi.youdao.com/")

print(driver.title)
print(driver.current_url)

#获取输入框
transMachine = driver.find_element(By.ID,"transMachine")

print(transMachine.size)
print(transMachine.text)
print(transMachine.get_attribute("href"))
print(transMachine.is_displayed())
print(transMachine.is_enabled())

3.窗口操作

  • maximize_window():最大化 → 模拟浏览器最大化按钮
  • set_window_size(100,100):浏览器大小 → 设置浏览器宽,高(像素点)
  • set_window_position(300,200):浏览器位置 → 设置浏览器位置
  • back():后退 → 模拟浏览器后退按钮
  • forward():前进 → 模拟浏览器前进按钮
  • refresh():刷新 → 模拟浏览器F5刷新
  • close():关闭 → 模拟浏览器关闭按钮(关闭单个窗口)
  • quit():关闭 → 关闭所有webDriver启动窗口

4.元素等待

翻页获取每页元素

from selenium import webdriver
from selenium.webdriver.common.by import by
from selenium.webdriver.common.keys import keys

driver = webdriver.Chrome("./chromedriver.exe")
#加载当当网
driver.get("https://www.dangdang.com/")

#获取输入框
key = driver.find_element(By.ID,"key_S")
key.send_keys("科幻")
#获取搜索框,点击搜索
search = driver.find_element(By.CSS_SELECTOR,".search .button")
search.click()
#获取商品标题及价格
for i in range(5):
  shoplist = driver.find_elements(By.CSS_SELECTOR,"./shoplist li")
  for li in shoplist:
    print(li.find_element(By.CSS_SELECTOR,"a").get_attribute("title"))
  #获取下一页按钮
  next = driver.find_element(By.LINK_TEXT,"下一页")
  next.click()

现在的网页越来越多采用了Ajax技术,这样程序便不能确定何时某个元素完全加载出来了,如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码直接使用了这个WebElement,那么就会抛出NullPointer的异常

为了避免这种元素定位困境而且会提高产生ElementNotVisibleException的概率,selenium提供了两种等待方式:显式等待和隐式等待

隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行

显式等待:指定某个条件,然后设置最长等待时间,如果在这个时间还没有找到元素,那么便会抛出异常了

显式等待使用WebDriverWait完成

webDriverWait(driver,timeout,poll_frequency=POLL_FREQUENCY,ignored_exception=None)
  • driver:所创建的浏览器driver
  • timeout:最长时间长度(默认单位:秒)
  • poll_frequency:间隔检测时长,默认0.5秒
  • ignored_exception:方法调用中忽略的异常,默认只抛出:找不到元素的异常

until:直到调用的方法返回值为True

until(method,message='')
  • method:excepted_conditions库中定义的方法
  • message:自定义报错信息

隐式等待:比较简单,就是设置全局元素查找到超时时间

implicity_wait(time_to_wait)

设置的时间单位为秒,例如implicity_wait(30),意思是超过30秒没有定位到一个元素,程序就会报错抛出异常,期间会一直轮询查找定位元素

三.页面操作

1.鼠标操作

  • context_click():右击 → 模拟鼠标右键点击效果
  • double_click():双击 → 模拟鼠标双击效果
  • drag_and_drop():拖动 → 模拟鼠标拖动效果
  • move_to_element():悬停 → 模拟鼠标悬停效果
  • perform():执行 → 用来执行以上所有的鼠标方法

2.键盘操作

  • send_keys(Keys.BACK_SPACE):删除键
  • send_keys(Keys.SPACE):空格键
  • send_keys(Keys.TAB):制表键
  • send_keys(Keys.ESCAPE):回退键
  • send_keys(Keys.ENTER):回车键
  • send_keys(Keys.CONTROL,'a'):全选
  • send_keys(Keys.CONTROL,'c'):复制

3.滚动条

#设置JavaScript脚本控制滚动条(0:左边距; 1000:上边距; 单位像素)
js = "window.scrollTo(0,1000)"
#WebDriver调用js脚本方法
driver.execite_script(js)

4.窗口截图

自动化脚本是由程序去执行的,因此有时候打印的错误信息并不是十分明确。如果在执行出错的时候对当前窗口截图保存,那么通过图片就可以非常直观地看到出错的原因

#截取当前窗口
driver.get_screenshot_as_file("./demo.png")

四.存储数据

1.将数据写入csv文件

#读写csv文件
import csv
#以写入方式打开文件,如果文件不存在则自动创建
f = open("d:/test.csv","w")
#获取csv writer,用于写入csv格式数据
writer = csv.writer(f)
#写入数据
writer.writerow(["张三","男","1.7"])
#关闭文件
f.close()

2.将数据写入MySQL

#安装模块
pip install pymysql

import pymysql
#创建链接
conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='',
                       db='tkql',charset='utf8')
#创建游标
cursor = conn.cursor()
#执行SQL,并返回受影响行数
effect_row = cursor.execute("select * from tb7")
#提交,不然无法保存新建或修改的数据
conn.commit()
#关闭游标
cursor.close()
#关闭链接
conn.close()

五.实战

1.访问有道翻译网站,输入单词,并获取翻译后的内容

from selenium import webdriver
from selenium.webdriver.common.by import by
from selenium.webdriver.common.keys import keys

driver = webdriver.Chrome("./chromedriver.exe")
#加载有道翻译页面
driver.get("https://fanyi.youdao.com/")
#获取输入框
input = driver.find_element(By.ID,"inputOriginal")
#输入内容
input.send_keys("hello")
#获取翻译按钮
tbtn = driver.find_element(By.ID,"transMachine")
#发现页面被遮挡,此时无法点击
#tbtn.click()

#先获取遮挡的广告条,点击关闭按钮
close_btn = driver.find_element(By.CSS_SELECTOR,".guide-con .guide-close")

#点击翻译
tbtn.click()

#获取翻译后的内容
transTarget = driver.find_element(By.ID,"transTarget")
print(transTarget.text)

2.获取代理

from selenium import webdriver
#myLog是自定义模块,也就是后来复制到当前目录的myLog.py文件
from myLog import MyLog as mylog

#这个类的作用是为了方便装载爬虫获取的数据,基本包含了网页的所有项
clas Item(object):
  ip = None #代理IP
  port = None #代理端口
  anonymous = None #是否匿名
  type = None #类型
  support = None #支持的协议
  local = None #物理地址
  speed = None #代理速度

#定义一个从kuaidili站点中获取proxy的类,这个类包含了3个类函数
class GetProxy(object):
  def __init__(self):
    self.startUrl = 'http://www.kuaidaili.com/proxylist/'
    self.log = mylog()
    self.urls = self.getUrls()
    self.proxyList = self.getProxyList(self.urls)
    self.fileName = 'proxy.txt'
    self.saveFile(self.fileName,self.proxyList)
  
  #该函数用于返回一个列表,这个列表包含了所有有效数据的网页地址
  def getUrls(self):
    urls = []
    for i in xrange(1,11):
      url = self.startUrl + str(i)
      urls.append(url)
      self.log.info('get url %s to urls' %usrl)
    return usrls
  
  #该函数用于从网页中获取有效数据,并保存到一个列表中
  def getProxyList(self,urls):
    browser = webdriver.PhantomJS()
    proxyList = []
    item = Item()
    for url in urls:
      browser.get(url)
      browser.implicitly_wait(5)
      elements = browser.find_elements_by_xpath('//tbody/tr')
      for element in elements:
        item.ip = element.find_element_by_xpath('/td[1]').text.encode('utf8')
        item.port = element.find_element_by_xpath('./td[2]').text.encode('utf8')
        item.anonymous = element.find_element_by_xpath('./td[3]').text.encode('utf8')
        item.type = element.find_element_by_xpath('./td[4]').text.encode('utf8')
        item.support element.find_element_by_xpath('./td[5]').text.encode('utf8')
        item.local = element.find_element_by_xpath('./td[6]').text.encode('utf8')
        item.speed = element.find_element_by_xpath('./td[7]').text.encode('utf8')
        proxyList.append(item)
        self.log.info('add proxy %s:$s to list' % (item.ip,item.port))
     browser.quit()
     return proxyList
  
  #该函数用于将所有列表中的数据保存到文件中
  def saveFile(self,fileName,proxyList):
    self.log.info('add all proxy to %s' % fileName)
    with open(fileName,'w') as fp:
      for item in proxyList:
        fp.write(item.ip + '\t')
        fp.write(item.port + '\t')
        fp.write(item.anonymous + '\t')
        fp.write(item.type + '\t')
        fp.write(item.support + '\t')
        fp.write(item.local + '\t')
        fp.write(item.speed + '\n')

if __name__ == '__main__':
  GP = GetProxy()

3.漫画爬虫

from selenium import webdriver
from mylog import MyLog as mylog
import os
import time

class GetCartoon(object):
  def __init__(self):
    self.startUrl = u'http://www.1kkk.com/ch1-406302/'
    self.log = mylog()
    self.browser = self.getBrowser()
    self.saveCartoon(self.browser)
 
  #作用是返回一个browser对象
  def getBrowser(self):
    browser = webdriver.PhantomJS()
    try:
      browser.get(self.startUrl)
    except:
      mylog.error('open the %s failed' %self.startUrl)
    #作用是设定了智能等待的最长时间
    browser.implicitly_wait(20)
    return browser

'''
这个函数将从网站中获取图片,并保存到新建立的文件夹中。文件夹的文字是从网页的title中获取的。从网页中获取了这个漫画的总页数,因为这个漫画在最后一页还是有“下一页”的按钮。没办法通过是否存在“下一页”按钮来确定是不是最后一页,所以必须先获取这个漫画的总页数'''
  def saveCartoon(self,browser):
    cartoonTitle = browser.title.split('_')[0]
    self.createDir(cartoonTitle)
    sumPage = int(self.browser.find_element_by_xpath('//font[@class="zf40"]/span[2]')
                                                     .text)
    i = 1
    while i <= sumPage:
      imgName = str(i) + '.png'
      browser.get_screenshot_as_file(imgName)
      self.log.info('save img %s' %imgName)
      i += 1
      NextTag = browser.find_element_by_id('text')
      NextTag.click()
      browser.implicitly_wait(20)
      time.sleep(5)
    self.log.info('save img sccess')
    exit()

  #作用是创建一个目录,为了防止有同名的目录,先在函数内做出判断
  def createDir(self,dirName):
    if os.path.exists(dirName):
      self.log.error('create directory %s failed,have a same name file or directory'
                     %dirName)
    else:
      try:
        os.makedirs(dirName)
      except:
        self.log.error('create directory %s failed' %dirName)
      else:
        self.log.info('create directory %s success' %dirName)

if __name__ == '__main__':
  GC = GetCartoon()
标签: 爬虫 selenium python

本文转载自: https://blog.csdn.net/happylls666/article/details/128403884
版权归原作者 奔跑的蜗牛君666 所有, 如有侵权,请联系我们删除。

“爬虫 | Selenium库”的评论:

还没有评论