2015-02-10 79 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

相關問題