我爱编程

【Python爬虫】selenium+Phantomjs

2018-03-25  本文已影响69人  倔强的潇洒小姐

工具简介:

1、selenium简介:
一个用于Web应用自动化程序测试的工具,测试直接运行在浏览器中,就像真正的用户在操作一样,它可以根据我们的指令、让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生,本身不带浏览器,不支持浏览器的功能,需要与第三方浏览器结合在一起才能使用,如Firefox,Chrome,也可以使用headless浏览器PhantomJS在后台执行,它可以用来爬取任何网页上看到的数据。

PS:selenium库有个叫webdriver的API,它可以加载网站的浏览器,也可以像BeautifulSoup一样用来定位元素

Selenium的下载与安装

使用代码测试:

from selenium import webdriver #导入包
driver = webdriver.Chrome()  #打开Chrome浏览器
driver.get("http://www.baidu.com/s?wd=python")  #输入url,百度搜索python

界面如下:

image.png

Selenium的优缺点

Selenium的操作
查找符合条件的单个元素:driver.find_element_by_name()
查找符合条件的一组元素:driver.find_elements_by_name()

点击查看更多操作

2、Phantomjs:Python爬虫利器
一个基于 WebKit 的服务器端 JavaScriptAPI,无界面(headless)浏览器,它会把网站加载到内存并执行页面上的JavaScript,是一个功能完善(虽然无界面)的浏览器,可以用于页面访问自动化,网络监测,网页截屏,以及无界面的Web测试等

PS:Phantomjs非一个Python的库,所以要去官网下载,安装后进行环境变量的设置

找不到Phantomjs.png

运行报错:Message 'phantomjs' executable needs to be in PATH?
解决办法:路径只写到bin有可能不够,把最后的可执行文件也要写上去
driver = webdriver.PhantomJS("G:/Program Files (x86)/Python/Scripts/phantomjs-2.1.1-windows/bin/phantomjs.exe")

元素的定位

对象的定位是通过属性定位来实现的,或是其他的一些信息来找到这个对象
如百度输入框源码:

百度输入框.png
# 通过id定位
inputid = driver.find_element_by_id("kw")
# 通过name属性定位
iuputname = driver.find_element_by_name("wd")
# 通过class属性定位
inputclass = driver.find_element_by_class_name("s_ipt")
# 通过标签属性定位
inputtagname = driver.find_element_by_tag_name("input")
# 通过css方式定位
inputcss = driver.find_element_by_css_selector("#kw")
# 通过xpath方式定位
inputxpath = driver.find_element_by_xpath("//*[@id='kw']")
# 获取标签的类型
print(inputid.tag_name)

浏览器操作

1、截屏:save_screenshot

url = "http://www.baidu.com"
driver.get(url)
time.sleep(1)
# 截屏获取浏览器页面
driver.save_screenshot("baidu.png")

2、前进与后退

# 发送数据请求
driver.get("http://www.baidu.com")
time.sleep(1)
# 截屏获取浏览器页面
driver.save_screenshot("baidu.png")
driver.get("http://www.youku.com")
driver.save_screenshot("youku.png")
# 后退
driver.back()
driver.save_screenshot("baidu2.png")
# 前进
driver.forward()
driver.save_screenshot("youku2.png")

对象操作,如全选、剪切

# 输入关键字
inputid.send_keys("python")
# 通过回车进行查询操作
inputid.send_keys(Keys.RETURN)
inputid.send_keys(Keys.ENTER)
# 暂停2秒,获取数据
#time.sleep(2)
#driver.set_page_load_timeout(2)
driver.save_screenshot("baidu3.png")
# 全选输入框内容
inputid.send_keys(Keys.CONTROL, "a")
driver.save_screenshot("baidu4.png")
# 剪切输入框内容
inputid.send_keys(Keys.CONTROL, "x")

# 获取查询按钮,并点击
button = driver.find_element_by_id("su").click()

实战环节

爬取淘宝网-波西米亚裙的商品信息,并把爬取的数据存储在MongoDB数据库中

  1. 访问淘宝网
  2. 分析搜索框的xpath语句,并send_keys("波西米亚裙");
  3. 分析页面,找到每条商品的信息,使用xpath提取数据并将其存储成字典的格式,进行输出;
  4. 找到下一页的按钮,模拟点击它,并循环第3步,直到循环结束 。

实现代码:

# -*- coding: utf-8 -*-
# __author__ = 'Carina'


from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from pyquery import PyQuery as pq
import re

#driver = webdriver.Chrome()
driver = webdriver.PhantomJS()
wait = WebDriverWait(driver, 10)
# 访问淘宝网,输入波希米亚裙
def search():
    try:
        driver.get("https://www.taobao.com")
        # 首页输入框
        input_box = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#q")))
        # 搜索按钮
        submit = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#J_SearchForm > button")))
        input_box.send_keys('波希米亚裙')
        submit.click()
        total = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.total")))
        # 调用函数--商品信息
        get_products()
        return total.text
    except TimeoutError:
        return search()

# 跳转到下一页
def next_page(page_number):
    try:
        # 底部页码输入框
        input_box = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input")))
        # 底部确定按钮
        submit = wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit")))
        input_box.clear()
        input_box.send_keys(page_number)
        submit.click()
        wait.until(ec.text_to_be_present_in_element((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > ul > li.item.active > span"), str(page_number)))
        get_products()
    except TimeoutError:
        next_page()

# 获取淘宝商品信息
def get_products():
    wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-itemlist.items.item")))
    html = driver.page_source
    doc = pq(html)   #pyquery (driver.page_source)就相当于requests.get获取的内容
    items = doc("#mainsrp-itemlist.items.item").items()
    for item in items:
        product = {
            "image": item.find('.pic .img').attr('src'),
            "price": item.find('.price').text(),
            "deal": item.find('.deal-cnt').text()[:-3],
            "title": item.find('.title').text(),
            "shop": item.find('.shop').text(),
            "location": item.find('.location').text(),            
        }
    print(product)

def main():
    total = search()
    total = int(re.compile('(\d+)').search(total).group(1))
    # 爬取所有的数据用total+1
    for i in range(2, 4):
        next_page(i)
        

if __name__ == "__main__":
    main()
    



PS:在学这块内容的时候,遇到问题了,然后去寻求答案,无意中看到了头条上的新闻,PhantomJS宣布终止开发,所以还是学习Firefox和Chrome吧


写在最后的话

1、常用的学习方法:边学边做
把自己学习成果分享出来,发在博客或者GitHub上,变成开源项目,成为自己的加分项
**2、常用的学习网站:GitHub
如何去使用Github?
1)点击Explore

image.png

2)向下拉找到“See more trending repositories”

image.png

3)点击选取感兴趣的语言方向

image.png

4)可以对感兴趣的项目进行Star操作

image.png

5)点击项目,可查看项目详情

image.png

扩展阅读:虫师:随笔分类 -seleniumPyquery包
上一篇下一篇

猜你喜欢

热点阅读