Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中抓取更新JavaScript页面_Python_Html_Selenium - Fatal编程技术网

在Python中抓取更新JavaScript页面

在Python中抓取更新JavaScript页面,python,html,selenium,Python,Html,Selenium,我一直在从事一个研究项目,希望获得一份来自巴西萱草的参考文章列表(所需的页面参考:,需要从以下页面的两个隐藏元素中收集:)。几周前我问了一个问题,这个问题得到了回答,我能够很好地解决这个问题,但现在我遇到了一个新的障碍,我不确定如何克服它 问题是,在填写第一个表单后,页面重定向到第二个页面,这是一个启用JavaScript/AJAX的页面,我需要通过点击页面顶部的按钮来完成所有匹配。我遇到的问题是,当单击“下一页”按钮时,我正在处理页面上正在更新的元素,这会导致过时的元素。我试图实现一些代码来检

我一直在从事一个研究项目,希望获得一份来自巴西萱草的参考文章列表(所需的页面参考:,需要从以下页面的两个隐藏元素中收集:)。几周前我问了一个问题,这个问题得到了回答,我能够很好地解决这个问题,但现在我遇到了一个新的障碍,我不确定如何克服它

问题是,在填写第一个表单后,页面重定向到第二个页面,这是一个启用JavaScript/AJAX的页面,我需要通过点击页面顶部的按钮来完成所有匹配。我遇到的问题是,当单击“下一页”按钮时,我正在处理页面上正在更新的元素,这会导致过时的元素。我试图实现一些代码来检测何时出现这种“过时”的效果,以指示页面已更改,但这并没有带来多少运气。以下是我实现的代码:

import urllib
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time

saveDir = "C:/tmp"

print("Opening Page...")

browser = webdriver.Chrome()
url = "http://bndigital.bn.gov.br/hemeroteca-digital/"
browser.get(url)

print("Searching for elements")

fLink = ""
fails = 0

frame_ref = browser.find_elements_by_tag_name("iframe")[0]
iframe = browser.switch_to.frame(frame_ref)
journal = browser.find_element_by_id("PeriodicoCmb1_Input")

search_journal = "Relatorios dos Presidentes dos Estados Brasileiros (BA)"
search_timeRange = "1890 - 1899"
search_text = "Milho"

xpath_form = "//input[@name=\'PesquisarBtn1\']"
xpath_journal = "//li[text()=\'"+search_journal+"\']"
xpath_timeRange = "//input[@name=\'PeriodoCmb1\' and not(@disabled)]"
xpath_timeSelect = "//li[text()=\'"+search_timeRange+"\']"
xpath_searchTerm = "//input[@name=\'PesquisaTxt1\']"

print("Locating Journal/Periodical")
journal.click()
dropDownJournal = WebDriverWait(browser, 60).until(EC.presence_of_element_located((By.XPATH, xpath_journal)))
dropDownJournal.click()
print("Waiting for Time Selection")
try:
    timeRange = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, xpath_timeRange)))
    timeRange.click()
    time.sleep(1)
    print("Locating Time Range")    
    dropDownTime = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, xpath_timeSelect)))
    dropDownTime.click()
    time.sleep(1)
except:
    print("Failed...")
print("Adding Search Term")

searchTerm = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, xpath_searchTerm)))
searchTerm.clear()
searchTerm.send_keys(search_text)
time.sleep(5)

print("Perform search")

submitButton = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, xpath_form)))
submitButton.click()

# Wait for the second page to load, pull what we need from it.
download_list = []

browser.switch_to_window(browser.window_handles[-1])
print("Waiting for next page to load...")

matches = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, "//span[@id=\'OcorNroLbl\']")))
print("Next page ready, found match element... counting")
countText = matches.text
countTotal = int(countText[countText.find("/")+1:])
print("A total of " + str(countTotal) + " matches have been found, standing by for page load.")
for i in range(1, countTotal+2):               
    print("Waiting for page " + str(i-1) + " to load...")
    while(fLink in download_list):
        try:
            jIDElement = browser.find_element_by_xpath("//input[@name=\'HiddenBibAlias\']")
            jPageElement = browser.find_element_by_xpath("//input[@name=\'hPagFis\']")
            fLink = "http://memoria.bn.br/DocReader/" + jIDElement.get_attribute('value') + "/" + jPageElement.get_attribute('value') + "&pesq=" + search_text         
        except:
            fails += 1
            time.sleep(1)
            if(fails == 10):
                print("Locked on a page, attempting to push to next.")
                nextPageButton = WebDriverWait(browser, 5).until(EC.presence_of_element_located((By.XPATH, "//input[@id=\'OcorPosBtn\']")))
                nextPageButton.click()                    
            #raise
        while(fLink == ""):
            jIDElement = browser.find_element_by_xpath("//input[@name=\'HiddenBibAlias\']")
            jPageElement = browser.find_element_by_xpath("//input[@name=\'hPagFis\']")
            fLink = "http://memoria.bn.br/DocReader/" + jIDElement.get_attribute('value') + "/" + jPageElement.get_attribute('value') + "&pesq=" + search_text                     
    fails = 0
    print("Link obtained: " + fLink)
    download_list.append(fLink)

    if(i != countTotal):
        print("Moving to next page...")
        nextPageButton = WebDriverWait(browser, 5).until(EC.presence_of_element_located((By.XPATH, "//input[@id=\'OcorPosBtn\']")))
        nextPageButton.click()
我正试图用这个块解决两个“bug”。首先,第一页在循环中总是被跳过(即:fLink=“”),即使其中有一个测试,我也不知道为什么会发生这种情况。另一个错误是,代码将完全随机地挂在特定页面上,唯一的出路是中断代码的执行


这个区块已经修改了几次,所以我知道这不是最“优雅”的解决方案,但我开始没有时间了。

在休息一天思考(并多睡一会儿)之后,我能够弄清楚到底发生了什么。上述代码有三个“大错误”。首先,它不处理StaleElementException和NosTouchElementException,后者可能在页面移动时发生。其次,循环条件反复检查页面不在列表中,当进入第一次运行时,允许空白状态直接加载,因为循环在第一次运行时从来没有执行过(应该在那里使用一个DO,但我做了更多的修改)。最后,我犯了一个愚蠢的错误,只检查第一个隐藏元素是否在更改,而实际上它是日志ID,并且在所有过程中几乎都是常量

修订开始时,对上的代码进行了修改,以实现“保持”条件,直到其中一个隐藏元素发生更改:

from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import NoSuchElementException
def hold_until_element_changed(driver, element1_xpath, element2_xpath, old_element1_text, old_element2_text):
    while True:
        try:
            element1 = driver.find_element_by_xpath(element1_xpath)
            element2 = driver.find_element_by_xpath(element2_xpath)
            if (element1.get_attribute('value') != old_element1_text) or (element2.get_attribute('value') != old_element2_text):
                break
        except StaleElementReferenceException:
            break
        except NoSuchElementException:
            return False
        time.sleep(1)
    return True    
然后我修改了原来的循环条件,返回到我创建的没有内部循环的原始“for loop”计数器,而不是调用上面的函数来创建“hold”,直到页面翻转为止,瞧,工作得很好。(注意:我还在下一页按钮上增加了超时,因为这是导致锁定条件的原因)


总而言之,一个好的思维练习和一些有用的链接让我在发表未来的问题时考虑。谢谢

我试图按照你提供的代码与你发布的链接进行对比,但它们似乎不在同一页面上。如果您用文字解释代码中表示的场景,这样我们就可以继续了。另外,在代码开始的页面上发布一个链接,这样我们就可以跟进了。当然,代码希望在特定的日志/时间段内删除所有命中实例。主页是。我已经有了填充表单的代码,它链接到日记账分录(第一个是上面提供的链接)。该程序的目标是从每次点击中获取两个隐藏的表单元素(名称为:hiddenbibbalias和hPagFis)。流程基本上是加载到日志页面,抓取两个隐藏的值并保存它们,然后转到下一页,循环直到完成所有操作。您是在解释程序的实现,而不是目标。你到底想做什么?我怀疑这个计划的目的是寻找隐藏的元素。您是否正在尝试为文档的各个页面捕获URL或下载页面的图像或???您的代码不是一个。您有未声明的变量。你从一个你没有告诉我们的页面开始。您将获得包含URL中随时可用的数据的隐藏元素。我仍然不明白你想做什么。我已经更新了原始帖子,包含了使用的完整代码。该程序的目标是在数据库中运行(使用日志、时间和搜索项的三个定义变量),并捕获单个结果的链接。然而,网站的建立方式,仅仅复制原始链接是不够的,您需要从搜索的每次点击中捕获两个隐藏元素,以便重建结果链接,我希望将其保存到输出文件(.txt)。如果不清楚,我很抱歉,上面的URL是“期望的结果”,是从隐藏字段构建的。
for i in range(1, countTotal+1):               
    print("Waiting for page " + str(i) + " to load...")
    bibxpath = "//input[@name=\'HiddenBibAlias\']"
    pagexpath = "//input[@name=\'hPagFis\']"
    jIDElement = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, bibxpath)))
    jPageElement = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, pagexpath)))
    jidtext = jIDElement.get_attribute('value')
    jpagetext = jPageElement.get_attribute('value')
    fLink = "http://memoria.bn.br/DocReader/" + jidtext + "/" + jpagetext + "&pesq=" + search_text         
    print("Link obtained: " + fLink)
    download_list.append(fLink)

    if(i != countTotal):
        print("Moving to next page...")
        nextPageButton = WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.XPATH, "//input[@id=\'OcorPosBtn\']")))
        nextPageButton.click()
        # Wait for next page to be ready
        change = hold_until_element_changed(browser, bibxpath, pagexpath, jidtext, jpagetext)
        if(change == False):
            print("Something went wrong.")