2015-07-15 12 views
7

Ho bisogno di scaricare alcuni dati dalla pagina, dove compilo il modulo (già fatto con mechanize). Il problema è che la pagina restituisce dati su molte pagine e ho problemi a ottenere i dati da quelle pagine.Mechanize e Python, facendo clic su href = "javascript: void (0);" collegamenti e ottenere la risposta indietro

Non c'è alcun problema a recuperarli dalla prima pagina dei risultati, poiché vengono visualizzati già dopo la ricerca: invio semplicemente il modulo e ottengo la risposta.

Ho analizzato il codice sorgente della pagina dei risultati e sembra che usi Java Script, RichFaces (un po 'di lib per JSF con ajax ma posso sbagliarmi visto che non sono un esperto di web).

Tuttavia, sono riuscito a capire come ottenere le restanti pagine dei risultati. Ho bisogno di fare clic sui link che si trovano in questa forma (href="javascript:void(0);", completa di codice sottostante):

<td class="pageNumber"><span class="rf-ds " id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233"><span class="rf-ds-nmb-btn rf-ds-act " id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_1">1</span><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_2">2</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_3">3</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_4">4</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_5">5</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_6">6</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_7">7</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_8">8</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_9">9</a><a class="rf-ds-nmb-btn " href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_10">10</a><a class="rf-ds-btn rf-ds-btn-next" href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_next">»</a><a class="rf-ds-btn rf-ds-btn-last" href="javascript:void(0);" id="SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_l">»»»»</a> 

<script type="text/javascript">new RichFaces.ui.DataScroller("SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233",function(event,element,data){RichFaces.ajax("SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233",event,{"parameters":{"SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233:page":data.page} ,"incId":"1"})},{"digitals":{"SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_9":"9","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_8":"8","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_7":"7","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_6":"6","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_5":"5","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_4":"4","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_3":"3","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_1":"1","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_10":"10","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_2":"2"} ,"buttons":{"right":{"SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_next":"next","SomeSimpleForm:SomeSimpleTable:j_idt211:j_idt233_ds_l":"last"} } ,"currentPage":1})</script></span></td> 
<td class="pageExport"><script type="text/javascript" src="/opi/javax.faces.resource/download.js?ln=js/component&amp;b="></script><script type="text/javascript"> 

quindi vorrei chiedere se c'è un modo per fare clic tutti i link e ottenere tutte le pagine che utilizzano meccanizzare (nota, che dopo il simbolo » ci sono più pagine disponibili)? Ho chiedere risposte per i manichini totali con conoscenze web :)

risposta

4

Prima di tutto, continuerei ad attenermi al selenio poiché questo è un sito web abbastanza "javascript-pesante". Si noti che è possibile utilizzare un browser senza testa (PhantomJS o con un virtual display) se necessario.

L'idea sarebbe quella di impaginare per 100 righe per pagina, fare clic sul collegamento ">>" fino a quando non è presente sulla pagina, il che significherebbe che abbiamo raggiunto l'ultima pagina e non ci sono più risultati per processi. Per rendere la soluzione affidabile, è necessario utilizzare Explicit Waits: ogni volta che si passa a una pagina successiva, attendere l'invisibilità dello spinner di caricamento.

implementazione di lavoro:

# -*- coding: utf-8 -*- 
from selenium.common.exceptions import NoSuchElementException 
from selenium.webdriver.common.by import By 
from selenium import webdriver 
from selenium.webdriver.support.select import Select 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 

driver = webdriver.Firefox() 
driver.maximize_window() 

driver.get('https://polon.nauka.gov.pl/opi/aa/drh/zestawienie?execution=e1s1') 
wait = WebDriverWait(driver, 30) 

# paginate by 100 
select = Select(driver.find_element_by_id("drhPageForm:drhPageTable:j_idt211:j_idt214:j_idt220")) 
select.select_by_visible_text("100") 

while True: 
    # wait until there is no loading spinner 
    wait.until(EC.invisibility_of_element_located((By.ID, "loadingPopup_content_scroller"))) 

    current_page = driver.find_element_by_class_name("rf-ds-act").text 
    print("Current page: %d" % current_page) 

    # TODO: collect the results 

    # proceed to the next page 
    try: 
     next_page = driver.find_element_by_link_text(u"»") 
     next_page.click() 
    except NoSuchElementException: 
     break 
+0

Sembra che la tua soluzione sia migliore.Ho aperto una nuova taglia per ringraziarti della tua risposta :) – yak

+0

@yak wow, grazie mille per questo. Sono contento che la risposta abbia aiutato a risolvere il problema. – alecxe

2

Questo funziona per me: sembra tutto il codice HTML è disponibile in page

import time  
from selenium import webdriver 
driver = webdriver.Firefox() 
driver.get('https://polon.nauka.gov.pl/opi/aa/drh/zestawienie') 

next_id = 'drhPageForm:drhPageTable:j_idt211:j_idt233_ds_next' 

pages = [] 
it = 0 
while it < 1795: 
    time.sleep(1) 
    it += 1 
    bad = True 
    while bad: 
     try: 
      driver.find_element_by_id(next_id).click() 
      bad = False 
     except: 
      print('retry') 

    page = driver.page_source 

    pages.append(page) 

Invece di prima raccolta e la conservazione di tutte html, si potrebbe anche solo chiedi quello che vuoi, ma avrai bisogno di lxml o BeautifulSoup per quello.

EDIT: Dopo averlo eseguito effettivamente ho notato che abbiamo sbagliato. È stato semplice rilevare l'eccezione e riprovare.

+0

Grazie mille per l'aiuto :) cercherò in un istante. Sì, sono d'accordo, ma BeautifulSoup non è un problema, l'ho usato prima, quindi penso che lo gestirò. Tuttavia, ho avuto problemi con il metodo 'send_keys', perché dopo che automaticamente (dal codice sorgente) ho fatto clic sul pulsante Cerca (Wyszukaj), la pagina ha cancellato automaticamente i criteri. Meh, a chi importa, se il tuo approccio funzionerà, userò semplicemente BS4 per l'analisi. – yak

+0

Oh, ho appena notato, sei il GUY di 'yagmail' - hai usato il tuo strumento, volevo solo ringraziarti per questo, è fantastico! – yak

+0

Buona fortuna! Piuttosto sicuro che funzionerà :) In effetti, è strano cosa fa esattamente la pagina, ma semplicemente riprovare l'elemento funziona ... Inoltre, se vuoi essere amichevole con la pagina e avere pazienza, sentiti libero di aggiungere più ritardo. – PascalVKooten

Problemi correlati