在新标签Selenium + Python中打开网页

问题描述 投票:13回答:6

所以我试图在我的WebDriver中的新标签上打开网站。我想这样做,因为使用PhantomJS为每个网站打开一个新的WebDriver需要大约3.5秒,我想要更快的速度......

我正在使用多进程python脚本,我想从每个页面获取一些元素,因此工作流程如下所示:

Open Browser

Loop throught my array
For element in array -> Open website in new tab -> do my business -> close it

但我找不到任何方法来实现这一目标。

这是我正在使用的代码。网站之间需要永远,我需要快速...其他工具是允许的,但我不知道有太多工具可以删除用JavaScript加载的网站内容(在加载时触发某些事件时创建的div)这是为什么我需要Selenium ... BeautifulSoup不能用于我的一些页面。

#!/usr/bin/env python
import multiprocessing, time, pika, json, traceback, logging, sys, os, itertools, urllib, urllib2, cStringIO, mysql.connector, shutil, hashlib, socket, urllib2, re
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from PIL import Image
from os import listdir
from os.path import isfile, join
from bs4 import BeautifulSoup
from pprint import pprint

def getPhantomData(parameters):
    try:
        # We create WebDriver
        browser = webdriver.Firefox()
        # Navigate to URL
        browser.get(parameters['target_url'])
        # Find all links by Selector
        links = browser.find_elements_by_css_selector(parameters['selector'])

        result = []
        for link in links:
            # Extract link attribute and append to our list
            result.append(link.get_attribute(parameters['attribute']))
        browser.close()
        browser.quit()
        return json.dumps({'data': result})
    except Exception, err:
        browser.close()
        browser.quit()
        print err

def callback(ch, method, properties, body):
    parameters = json.loads(body)
    message = getPhantomData(parameters)

    if message['data']:
        ch.basic_ack(delivery_tag=method.delivery_tag)
    else:
        ch.basic_reject(delivery_tag=method.delivery_tag, requeue=True)

def consume():
    credentials = pika.PlainCredentials('invitado', 'invitado')
    rabbit = pika.ConnectionParameters('localhost',5672,'/',credentials)
    connection = pika.BlockingConnection(rabbit)
    channel = connection.channel()

    # Conectamos al canal
    channel.queue_declare(queue='com.stuff.images', durable=True)
    channel.basic_consume(callback,queue='com.stuff.images')

    print ' [*] Waiting for messages. To exit press CTRL^C'
    try:
        channel.start_consuming()
    except KeyboardInterrupt:
        pass

workers = 5
pool = multiprocessing.Pool(processes=workers)
for i in xrange(0, workers):
    pool.apply_async(consume)

try:
    while True:
        continue
except KeyboardInterrupt:
    print ' [*] Exiting...'
    pool.terminate()
    pool.join()
python selenium webdriver phantomjs
6个回答
27
投票

您可以通过组合键COMMAND + T或COMMAND + W(OSX)来实现选项卡的打开/关闭。在其他操作系统上,您可以使用CONTROL + T / CONTROL + W.

在硒中你可以模仿这种行为。您将需要创建一个webdriver和多个选项卡作为您需要的测试。

这是代码。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.google.com/")

#open tab
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't') 
# You can use (Keys.CONTROL + 't') on other OSs

# Load a page 
driver.get('http://stackoverflow.com/')
# Make the tests...

# close the tab
# (Keys.CONTROL + 'w') on other OSs.
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') 


driver.close()

15
投票

这是从另一个示例改编的常见代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.google.com/")

#open tab
# ... take the code from the options below

# Load a page 
driver.get('http://bings.com')
# Make the tests...

# close the tab
driver.quit()

可能的方式是:

  1. <CTRL> + <T>发送到一个元素 #open tab driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
  2. 通过Action链发送<CTRL> + <T> ActionChains(driver).key_down(Keys.CONTROL).send_keys('t').key_up(Keys.CONTROL).perform()
  3. 执行一个javascript代码段 driver.execute_script('''window.open("http://bings.com","_blank");''') 为了实现这一目标,您需要确保正确设置首选项browser.link.open_newwindowbrowser.link.open_newwindow.restriction。最新版本中的默认值是可以的,否则您需要: fp = webdriver.FirefoxProfile() fp.set_preference("browser.link.open_newwindow", 3) fp.set_preference("browser.link.open_newwindow.restriction", 2) driver = webdriver.Firefox(browser_profile=fp) 问题是那些偏好预设为other values并且至少冻结了硒3.4.0。当您使用配置文件使用java绑定设置它们时,会出现exception,并且使用python绑定时,将忽略新值。 在Java中,有一种方法可以在与geckodriver交谈时设置这些首选项而无需指定配置文件对象,但它似乎尚未在python绑定中实现: FirefoxOptions options = new FirefoxOptions().setProfile(fp); options.addPreference("browser.link.open_newwindow", 3); options.addPreference("browser.link.open_newwindow.restriction", 2); FirefoxDriver driver = new FirefoxDriver(options);

第三个选项在selenium 3.4.0中为qthon做了stop working

在硒3.4.0中,前两个选项似乎也适用于stop working。它们依赖于将CTRL键事件发送到元素。乍一看似乎这是CTRL键的问题,但由于新的multiprocess feature of Firefox它失败了。可能这个新架构强加了新的方法,或者可能是一个临时的实现问题。无论如何我们可以通过以下方式禁用

fp = webdriver.FirefoxProfile()
fp.set_preference("browser.tabs.remote.autostart", False)
fp.set_preference("browser.tabs.remote.autostart.1", False)
fp.set_preference("browser.tabs.remote.autostart.2", False)

driver = webdriver.Firefox(browser_profile=fp)

...然后你可以成功使用第一种方式。


12
投票
browser.execute_script('''window.open("http://bings.com","_blank");''')

浏览器是webDriver的地方


4
投票

使用Selenium v​​3.x,通过Python在New Tab中打开一个网站现在要容易得多。这是一个解决方案,您可以在相邻的TAB中的初始TAB和http://www.google.co.in中打开https://www.yahoo.com

  • 代码块: from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC options = webdriver.ChromeOptions() options.add_argument("start-maximized") options.add_argument('disable-infobars') driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe') driver.get("http://www.google.co.in") print("Initial Page Title is : %s" %driver.title) windows_before = driver.current_window_handle print("First Window Handle is : %s" %windows_before) driver.execute_script("window.open('https://www.yahoo.com')") WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2)) windows_after = driver.window_handles new_window = [x for x in windows_after if x != windows_before][0] driver.switch_to_window(new_window) print("Page Title after Tab Switching is : %s" %driver.title) print("Second Window Handle is : %s" %new_window)
  • 控制台输出: Initial Page Title is : Google First Window Handle is : CDwindow-B2B3DE3A222B3DA5237840FA574AF780 Page Title after Tab Switching is : Yahoo Second Window Handle is : CDwindow-D7DA7666A0008ED91991C623105A2EC4
  • 浏览器快照:

multiple__tabs


3
投票

经过这么长时间的努力,以下方法对我有用:

driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)

windows = driver.window_handles

time.sleep(3)
driver.switch_to.window(windows[1])

0
投票

我试了很长时间在Chrome上运行使用action_keys和body_keys运行的标签。唯一对我有用的是回答here。这就是我的重复标签def最终看起来像,可能不是最好的,但它对我来说很好。

def duplicate_tabs(number, chromewebdriver):
#Once on the page we want to open a bunch of tabs
url = chromewebdriver.current_url
for i in range(number):
    print('opened tab: '+str(i))
    chromewebdriver.execute_script("window.open('"+url+"', 'new_window"+str(i)+"')")

它基本上是从python内部运行一些java,它非常有用。希望这有助于某人。

注意:我使用的是Ubuntu,它不应该有所作为,但如果它不适合你,这可能是原因。


-1
投票

奇怪的是,这么多的答案,所有这些答案都使用了JS和键盘快捷键这样的代理,而不仅仅是使用了selenium功能:

def newTab(driver, url="about:blank"):
    wnd = driver.execute(selenium.webdriver.common.action_chains.Command.NEW_WINDOW)
    handle = wnd["value"]["handle"]
    driver.switch_to.window(handle)
    driver.get(url) # changes the handle
    return driver.current_window_handle
© www.soinside.com 2019 - 2024. All rights reserved.