selenium+phantomjs/Chrome/Firefox

selenium+phantomjs/Chrome/Firefox

一selenium

1.定义

1、Web自动化测试工具,可运行在浏览器,根据指令操作浏览器
2、只是工具,必须与第三方浏览器结合使用

2.安装

Linux: sudo pip3 install selenium
Windows: python -m pip install selenium

phantomjs浏览器

1.定义

  无界面浏览器(又称无头浏览器),在内存中进行页面加载,高效

2.安装(phantomjs、chromedriver、geckodriver)

Windows

1、下载对应版本的phantomjs、chromedriver、geckodriver
2、把chromedriver.exe拷贝到python安装目录的Scripts目录下(添加到系统环境变量)
   # 查看python安装路径: where python
3、验证
   cmd命令行: chromedriver

# 下载地址
1、chromedriver : 下载对应版本
http://chromedriver.storage.googleapis.com/index.html
2、geckodriver
https://github.com/mozilla/geckodriver/releases
3、phantomjs
https://phantomjs.org/download.html

Linux

1、下载后解压
   tar -zxvf geckodriver.tar.gz 
2、拷贝解压后文件到 /usr/bin/ (添加环境变量)
   sudo cp geckodriver /usr/bin/
3、更改权限
   sudo -i
   cd /usr/bin/
   chmod 777 geckodriver

3.使用

示例代码一:使用 selenium+浏览器 打开百度

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')
browser.save_screenshot('baidu.png')
browser.quit()

示例代码二:打开百度,搜索赵丽颖,查看

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('http://www.baidu.com/')

# 向搜索框(id kw)输入 赵丽颖
ele = browser.find_element_by_xpath('//*[@id="kw"]')
ele.send_keys('赵丽颖')

time.sleep(1)
# 点击 百度一下 按钮(id su)
su = browser.find_element_by_xpath('//*[@id="su"]')
su.click()

# 截图
browser.save_screenshot('赵丽颖.png')
# 关闭浏览器
browser.quit()

浏览器对象(browser)方法

1、browser = webdriver.Chrome(executable_path='path')
2、browser.get(url)
3、browser.page_source # 查看响应内容
4、browser.page_source.find('字符串')
   # 从html源码中搜索指定字符串,没有找到返回:-1
5、browser.quit() # 关闭浏览器

定位节点

单元素查找(一个节点对象)

1、browser.find_element_by_id('')
2、browser.find_element_by_name('')
3、browser.find_element_by_class_name('')
4、browser.find_element_by_xpath('')

多元素查找([节点对象列表])

1、browser.find_elements_by_id('')
2、browser.find_elements_by_name('')
3、browser.find_elements_by_class_name('')
4、browser.find_elements_by_xpath('')

节点对象操作

1、ele.send_keys('') # 搜索框发送内容
2、ele.click()
3、ele.text          # 获取文本内容,包含自己诶单和后代节点的文本内容
4、ele.get_attribute('src') # 获取属性值

京东爬虫案例

目标

1、目标网址 :https://www.jd.com/
2、抓取目标 :商品名称、商品价格、评价数量、商品商家

思路提醒

1、打开京东,到商品搜索页
2、匹配所有商品节点对象列表
3、把节点对象的文本内容取出来,查看规律,是否有更好的处理办法?
4、提取完1页后,判断如果不是最后1页,则点击下一页
   # 如何判断是否为最后1页???

实现步骤

1.找节点

1、首页搜索框 : //*[@id="key"]
2、首页搜索按钮   ://*[@id="search"]/div/div[2]/button
3、商品页的 商品信息节点对象列表 ://*[@id="J_goodsList"]/ul/li

2.执行JS脚本,获取动态加载数据

browser.execute_script(
    'window.scrollTo(0,document.body.scrollHeight)'
)

3.代码实现

from selenium import webdriver
import time

class JdSpider(object):
    def __init__(self):
        self.browser = webdriver.Chrome()
        self.url = 'https://www.jd.com/'
        self.i = 0

    # 获取商品页面
    def get_page(self):
        self.browser.get(self.url)
        # 找2个节点
        self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书籍')
        self.browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
        time.sleep(2)

    # 解析页面
    def parse_page(self):
        # 把下拉菜单拉到底部,执行JS脚本
        self.browser.execute_script(
            'window.scrollTo(0,document.body.scrollHeight)'
        )
        time.sleep(2)
        # 匹配所有商品节点对象列表
        li_list = self.browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
        for li in li_list:
            li_info = li.text.split('\n')
            if li_info[0][0:2] == '每满':
                price = li_info[1]
                name =li_info[2]
                commit = li_info[3]
                market = li_info[4]
            else:
                price = li_info[0]
                name = li_info[1]
                commit = li_info[2]
                market = li_info[3]
            print('\033[31m************************************\033[0m')
            print(price)
            print(commit)
            print(market)
            print(name)
            self.i += 1

    # 主函数
    def main(self):
        self.get_page()
        while True:
            self.parse_page()
            # 判断是否该点击下一页,没有找到说明不是最后一页
            if self.browser.page_source.find('pn-next disabled') == -1:
                self.browser.find_element_by_class_name('pn-next').click()
                time.sleep(2)
            else:
                break
        print(self.i)

if __name__ == '__main__':
    spider = JdSpider()
    spider.main()
代码实现
import requests
from selenium import webdriver
import time


class JdSpider():
  def __init__(self):
    self.url = 'https://www.jd.com'
    #设置无界面浏览器
    self.options = webdriver.ChromeOptions()
    self.options.add_argument('--headless')
    #正常创建浏览器对象即可
    self.browser = webdriver.Chrome(options=self.options)
  # 获取页面信息
  def get_html(self):
    self.browser.get(self.url)
    # 搜索框
    self.browser.find_element_by_xpath('//*[@id="key"]').send_keys('爬虫书')
    # 搜索按钮
    self.browser.find_element_by_xpath('//*[@id="search"]/div/div[2]/button').click()
    time.sleep(2.3)
    # 添加计数
    self.i = 0

  # 解析页面
  def parse_html(self):
    #把进度条拉倒底部,是所有数据动态加载
    self.browser.execute_script(
      'window.scrollTo(0,document.body.scrollHeight)'
    )
    #等待动态数据加载完成
    time.sleep(2)
    item = {}
    # 先提取所有商品节点对象列表,li列表
    li_list = self.browser.find_elements_by_xpath('//*[@id="J_goodsList"]/ul/li')
    for li in li_list:
      # find_element
      item['name'] = li.find_element_by_xpath('.//div[@class="p-name"]/a/em').text.strip()
      item['price'] = li.find_element_by_xpath('.//div[@class="p-price"]').text.strip()
      item['comment'] = li.find_element_by_xpath('.//div[@class="p-commit"]/strong').text.strip()
      item['shop'] = li.find_element_by_xpath('.//div[@class="p-shopnum"]').text.strip()
      print(item)
      self.i += 1

  def main(self):
    self.get_html()
    while True:
      self.parse_html()
      # 判断是否为最后一页
      if self.browser.page_source.find('pn-next disabled') == -1:
        self.browser.find_element_by_class_name('pn-next').click()
        time.sleep(2)
      else:
        break
    print('数量', self.i)

    self.browser.quit()

if __name__ == '__main__':
  jd = JdSpider()
  jd.main()
代码实现2

 

posted @ 2019-08-15 20:52  maplethefox  阅读(321)  评论(0编辑  收藏  举报