【问题标题】:My script produces javascript stuffs Instead of valid links我的脚本生成 javascript 东西而不是有效链接
【发布时间】:2017-06-20 14:24:01
【问题描述】:

运行我的脚本,我得到“javascript:getDetail(19978)”之类的项目,例如 href。大括号中的数字如果与“https://www.aopa.org/airports/4M3/business/”连接,则生成有效链接。但是,单击这个新创建的链接,我可以看到它让我进入另一个页面,如果从原始页面链接单击,该页面与该页面不同。如何获取原始链接而不是“javascript:getDetail(19978)”。应在搜索框中写下“全部”进行搜索。 我试过的代码:

from selenium import webdriver
import time
link = "https://www.aopa.org/airports/4M3/business/"
driver = webdriver.Chrome()
driver.get("https://www.aopa.org/learntofly/school/")

driver.find_element_by_id('searchTerm').send_keys('All')
driver.find_element_by_id('btnSearch').click()
time.sleep(5)
for pro in driver.find_elements_by_xpath('//td/a'):
    print(pro.get_attribute("href"))
driver.quit()

使用我在描述中粘贴的基本网址创建新链接的代码:

from selenium import webdriver
import time
link = "https://www.aopa.org/airports/4M3/business/"
driver = webdriver.Chrome()
driver.get("https://www.aopa.org/learntofly/school/")
driver.find_element_by_id('searchTerm').send_keys('All')
driver.find_element_by_id('btnSearch').click()
time.sleep(5)
for item in driver.find_elements_by_xpath('//td/a'):
    fresh = item.get_attribute("href").replace("javascript:getDetail(","")
    print(link + fresh.replace(")",""))
driver.quit()

但是,这个新创建的链接将我带到不同的目的地。

FYC,原始链接嵌入在如下元素中:

<td><a href="javascript:getDetail(19978)">GOLD DUST FLYING SERVICE, INC.</a></td>

【问题讨论】:

  • 我对接受哪个答案感到非常困惑,因为两个蟒蛇巨头在下面给出的答案都很有魅力。
  • 如果我出错了,不要责骂我或采取其他方式。安德森爵士首先给出了答案,所以我会接受它。不过,我对这两个答案都投了赞成票。
  • 别担心。重要的是问题解决了。谢谢你的好问题!

标签: python-3.x selenium selenium-webdriver web-scraping web-crawler


【解决方案1】:

单击链接您会创建一个XHR。页面实际上保持不变,但从 JSON 接收到的数据呈现而不是以前的内容。

如果您想在HTML 页面中打开原始数据,您可以尝试类似

# To get list of entries as ["19978", "30360", ... ]
entries = [a.get_attribute('href').split("(")[1].split(")")[0] for a in driver.find_elements_by_xpath('//td/a')]
url = "https://www.aopa.org/learntofly/school/wsSearch.cfm?method=schoolDetail&businessId="
for entry in entries:
    driver.get(url + entry)
    print(driver.page_source)

您也可以使用requests 来获取每个JSON 响应

import requests
for entry in entries:
    print(requests.get(url + entry).json())

没有在浏览器中呈现数据

【讨论】:

  • 感谢 Andersson 先生的无斑点解决方案。
  • 安德森爵士,您能否给我一个提示,您是从哪里发现这个“aopa.org/learntofly/school/…”链接的?提前致谢。
  • 在浏览器中按F12-> 切换到“网络”(“Net”)选项卡-> 切换到“XHR”选项卡-> 点击所需链接...您会看到发送了新的请求。点击新的请求条目 -> 勾选“Headers”->“RequestURL”
【解决方案2】:

如果您查看源代码中的getDetail() 是如何实现的,并在单击每个搜索结果链接时探索“网络”选项卡,您可能会看到针对一个结果发出了多个 XHR 请求,并且有执行一些客户端逻辑以形成搜索结果页面。

如果您不想深入复制形成每个搜索结果页面的所有逻辑 - 只需在搜索结果页面和单个搜索结果页面之间来回切换:

from selenium import webdriver

from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)

driver.get("https://www.aopa.org/learntofly/school/")
driver.find_element_by_id('searchTerm').send_keys('All')
driver.find_element_by_id('btnSearch').click()

# wait for search results to be visible
table = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#searchResults table")))

for index in range(len(table.find_elements_by_css_selector('td a[href*=getDetail]'))):
    wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#searchResults table")))

    # get the next link
    link = table.find_elements_by_css_selector('td a[href*=getDetail]')[index]
    link_text = link.text
    link.click()

    print(link_text)
    # TODO: get details

    # go back
    back_link = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#schoolDetail a[href*=backToList]")))
    driver.execute_script("arguments[0].click();", back_link)

driver.quit()

注意使用Explicit Waits 而不是硬编码的“睡眠”。


在这里完全避免使用 selenium 并“无头”解决问题实际上可能是有意义的 - 向网站的 API 发出 HTTP 请求(通过 requests 模块)。

【讨论】:

  • 感谢 alecxe 先生,为您提供完美的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
相关资源
最近更新 更多