爬虫-Selenium和PhantomJS

Selenium

Selenium是什么?

  • Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成 .Net、Java、Perl等不同语言的测试脚本。

  • Selenium是一个Python的一个第三方库,对外提供的接口可以操作你的浏览器,然后让浏览器完成自动化的操作。

使用Selenium

  • 安装
    1
    pip install selenium
  • 操作谷歌浏览器,首先必须有谷歌浏览器的一个驱动
  • 谷歌驱动下载
  • 谷歌驱动和谷歌浏览器版本关系映射表
  • 火狐驱动下载
  • IE驱动下载
  • 下载完谷歌浏览器的驱动后,将解压后的文件放到python安装目录下的Scripts目录下,这样以后就不用指定驱动路径了

代码操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from selenium import webdriver
browser = webdriver.Chrome(path)
browser.get()
browser.quit()

使用下面的方法,查找指定的元素进行操作即可
find_element_by_id 根据id找节点
find_elements_by_name 根据name找
find_elements_by_xpath 根据xpath查找
find_elements_by_tag_name 根据标签名找
find_elements_by_class_name 根据class名字查找
find_elements_by_css_selector 根据选择器查找
find_elements_by_link_text 根据链接内容查找

get\send_keys\click

示例1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from selenium import webdriver
import time


def main():
# 模拟创建一个浏览器对象,然后通过对象去操作浏览器
browser = webdriver.Chrome()
url = 'https://www.baidu.com/'
browser.get(url)
time.sleep(1)
# 查找input输入框
my_input = browser.find_element_by_id('kw')
# 往搜索框里写文字
my_input.send_keys('美女')
time.sleep(1)
# 查找“百度一下”按钮
button = browser.find_elements_by_class_name('s_btn')[0]
button.click()
time.sleep(2)
# 找到指定的图片点击
image = browser.find_elements_by_class_name('op-img-covers-link-imgs')[0]
image.click()
time.sleep(2)
# 关闭浏览器(退出浏览器)
browser.quit()


if __name__ == '__main__':
main()

示例2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from selenium import webdriver
from time import sleep

# 后面是你的浏览器驱动位置,记得前面加r'','r'是防止字符转义的
driver = webdriver.Chrome(r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\chromedriver.exe')
# 用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)
# 在打开的页面中找到“美女_百度图片”,并打开这个页面
driver.find_elements_by_link_text('美女_百度图片')[0].click()
sleep(3)

# 关闭浏览器
driver.quit()

PhantomJS

PhantomJS是什么?

  • PhantomJS 是一个基于Webkit的“无界面”(headless)浏览器,它会把网站加载到内存并执行页面上的 JavaScript,因为不会展示图形界面,所以运行起来比完整的浏览器要高效
  • 如果我们把 Selenium 和 PhantomJS 结合在一起,就可以运行一个非常强大的网络爬虫了,这个爬虫可以处理 JavaScrip、Cookie、headers,以及任何我们真实用户需要做的事情
  • Selenium + PhantomJS 就是爬虫终极解决方案
  • ⚠️PhantomJS的Selenium支持已经被弃用,请使用Chrome或Firefox的无头版本

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from time import sleep
from selenium import webdriver


def main():
# phantomjs路径
path = r'C:\Users\suyin\Desktop\review\爬虫\day05\phantomjs-2.1.1-windows\bin\phantomjs.exe'
# 模拟创建一个浏览器对象,然后通过对象去操作浏览器
browser = webdriver.PhantomJS(path)
# 打开百度
url = 'https://www.baidu.com/'
browser.get(url)
sleep(2)
# 拍照
browser.save_screenshot(r'phantomjs\baidu.png')

# 查找input输入框
my_input = browser.find_element_by_id('kw')
# 往搜索框里写文字
my_input.send_keys('美女')
sleep(1)
browser.save_screenshot(r'phantomjs\meinv.png')

# 查找“百度一下”按钮
button = browser.find_elements_by_class_name('s_btn')[0]
button.click()
sleep(1)
browser.save_screenshot(r'phantomjs\show.png')

# 关闭浏览器(退出浏览器)
browser.quit()


if __name__ == '__main__':
main()

下拉滚动条到底部

豆瓣电影下拉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from time import sleep
from selenium import webdriver


def main():
# phantomjs路径
path = r'C:\Users\suyin\Desktop\review\爬虫\day05\phantomjs-2.1.1-windows\bin\phantomjs.exe'
# 模拟创建一个浏览器对象,然后通过对象去操作浏览器
browser = webdriver.PhantomJS(path)
url = r'https://movie.douban.com/typerank?type_name=%E5%8A%A8%E4%BD%9C&type=5&interval_id=100:90&action='
browser.get(url)
sleep(2)
browser.save_screenshot(r'phantomjs\douban1.png')

# 让browser执行简单的js代码,模拟滚动条滚动到底部,仅对PhantomJS有用
js = 'document.body.scrollTop=10000'
browser.execute_script(js)
sleep(2)
browser.save_screenshot(r'phantomjs\douban2.png')

# 获取网页的代码,保存到文件中
html = browser.page_source
with open(r'phantomjs\douban.html', 'w', encoding='utf8') as fp:
fp.write(html)

# 关闭浏览器(退出浏览器)
browser.quit()


if __name__ == '__main__':
main()

python中selenium操作下拉滚动条方法汇总

图片加载

  • 图片懒加载
  • 获取网页的代码: browser.page_source
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    from selenium import webdriver
    import time

    path = r'C:\Users\ZBLi\Desktop\1801\day05\ziliao\phantomjs-2.1.1-windows\bin\phantomjs.exe'
    browser = webdriver.PhantomJS(path)

    url = 'http://sc.chinaz.com/tag_tupian/OuMeiMeiNv.html'

    browser.get(url)
    time.sleep(3)
    with open(r'phantomjs\tupian1.html', 'w', encoding='utf8') as fp:
    fp.write(browser.page_source)

    js = 'document.body.scrollTop=10000'
    browser.execute_script(js)
    time.sleep(3)

    with open(r'phantomjs\tupian2.html', 'w', encoding='utf8') as fp:
    fp.write(browser.page_source)

    browser.quit()

登录

  • 前面讲的登录过程:直接抓包找到post地址,发送过去即可登录成功
  • 现在的登录过程:直接抓包发送post不行,因为表单中有一些数据需要从网页中获取到,比如这里的formhash。那么,现在的登录过程,就变成了,先发送get请求到登录页面,然后通过xpath、bs获取需要的表单令牌,然后再发送post请求,开始登录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import urllib.request
import urllib.parse

'''
1、前面讲的登录过程:直接抓包找到post地址,发送过去即可登录成功
2、现在的登录过程:直接抓包发送post不行,因为表单中有一些数据需要从网页中获取到,比如这里的formhash。那么,现在的登录过程,就变成了,先发送get请求到登录页面,然后通过xpath、bs获取需要的表单令牌,然后再发送post请求,开始登录
'''

url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LCGbY'

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
}

formdata = {
# 表单令牌
'formhash': '7e549c64',
'referer': 'http://bbs.chinaunix.net/',
'username': 'wolfmonkey',
'password': 'lizhibin666',
'loginsubmit': 'true',
'return_type': '',
}

formdata = urllib.parse.urlencode(formdata).encode()
request = urllib.request.Request(url=url, headers=headers)

response = urllib.request.urlopen(request, data=formdata)

# print(response.read().decode('gbk'))
with open('unix.html', 'wb') as fp:
fp.write(response.read())

Headless Chrome

  • Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。相比于现代浏览器,Headless Chrome 更加方便测试 web 应用,获得网站的截图,做爬虫抓取信息等。相比于出道较早的 PhantomJS,SlimerJS 等,Headless Chrome 则更加贴近浏览器环境。
  • 为什么使用它?因为PhantomJS现在都不维护了!
  • 目前在Mac和Linux上,Chrome版本号在59+以上,才支持这种模式;在Windows上,要求Chrome版本号在60+以上,才支持这种模式!
    1
    2
    3
    4
    from selenium.webdriver.chrome.options import Options
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--disable-gpu')
  • 示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    from time import sleep
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options

    # 创建一个参数对象,用来控制chrome以无界面模式打开
    chrome_options = Options()
    # 以无界面模式运行Chrome
    chrome_options.add_argument('--headless')
    # --disable-gpu 主要是为了屏蔽现阶段可能触发的错误,在Windows上运行时需要
    chrome_options.add_argument('--disable-gpu')
    # 设置无界面浏览器尺寸
    chrome_options.add_argument('--window-size=1920,1080')


    def main():
    # 模拟创建一个浏览器对象,然后通过对象去操作浏览器
    browser = webdriver.Chrome(options=chrome_options)
    url = 'https://www.baidu.com/'
    browser.get(url)
    # 关闭浏览器(退出浏览器)
    sleep(2)
    browser.save_screenshot('baidu.png')
    browser.quit()


    if __name__ == '__main__':
    main()

  • 参数说明 browser = webdriver.Chrome(参数)
    • executable_path:可执行文件的路径。如果使用默认值,则假定可执行文件在$PATH中
    • port:您希望服务运行的端口,如果保留为0,将会找到一个空闲端口
    • options:这需要一个ChromeOptions实例
    • service_args:传递给驱动程序服务的参数列表
    • desired_capabilities:具有非浏览器特定的字典对象,仅限功能,如“proxy”或“loggingPref”
    • service_log_path:记录驱动信息的路径
    • chrome_options:已弃用的选项参数
    • keep_alive:是否配置ChromeRemoteConnection以使用HTTP keep alive