2015-02-10 81 views
5

所以我试图在我的WebDriver里面的新选项卡上打开网站。我想这样做,因为为每个网站打开一个新的WebDriver大约需要3.5秒使用PhantomJS,我想要更多的速度...在新标签中打开网页Selenium + Python

我使用多进程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() 
+0

如何在开始时创建所有WebDriver? – Raito 2015-02-10 13:48:41

回答

17

可以通过键COMMAND + TCOMMAND + W(OSX)的组合实现了选项卡的打开/关闭。在其他SO上,您可以使用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') 

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

# close the tab 
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 'w') 
driver.close() 
+0

但是我有多进程,所以,我有10个同时工作,想要访问每个页面中的数据,这样做(我试过)以吨标签打开结束,但只有一个查找元素和做生意 – 2015-02-10 14:44:25

+0

对不起,我做没有得到你的声明。你的问题是“对于数组中的元素 - >在新选项卡中打开网站 - >做我的生意 - >关闭它”。所提出的解决方案试图回答它。你能澄清你到底在找什么吗?你确定webdriver是你正确的工具吗?什么是scrapy? – aberna 2015-02-10 14:50:30

+0

我正在做的是创建n个工作人员(在这种情况下是10个工作人员),每个工作人员需要打开一个URL然后在该URL上放弃一些东西,主要问题是它极其缓慢,因为它需要打开一个新的webdriver在每次迭代中,这需要大约4秒。我认为这对我来说是正确的工具,因为网站上加载了一些图片,只有当加载JavScript时才加载图片,否则不会创建元素,当然也不会被废弃 – 2015-02-10 14:58:33

0

基础上硒网站上的定义: 首先,它是自动化测试目的的Web应用程序,但当然不限于这一点。无聊的基于Web的管理任务可以(也应该)也自动化。 您看到硒的主要目标是用于测试目的,除此之外,您可以自动执行管理任务而不爬取网站。 使用这种东西爬行的目的只是浪费时间 我应该专注于抓取的东西,看看http://scrapy.org 这是python中最常见的框架,用于从网站获取数据。

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

浏览器webdriver的

+0

这是唯一一个为我工作的原因。谢谢! – Mangohero1 2018-01-12 00:34:11

0

挣扎了这么久以下方法后为我工作:

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

你用最近的版本测试过了吗?它不适合我。 我认为,在你的情况下,你失去了焦点出于某种原因。 – yucer 2017-08-04 08:56:25

5

这是改编自另一个例子通用代码:

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. 经由动作链发送<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时指定一个配置文件对象的方式,但它似乎不是在蟒蛇尚未实现绑定:

    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); 
    

的第三个选项是012.for python in 3.4.0。

前两个选项在硒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) 

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

+0

这个命令实际上工作了! – Sandeep 2018-01-28 03:57:44

相关问题