如何使用Python从包含JavaScript的<a>标签获取href?

时间:2019-09-11 06:51:49

标签: javascript python selenium web-scraping

我正在尝试使用Python + Selenium从标记中获取href,但是href中包含"JavaScript"。因此我无法获取目标URL。

我正在使用Python 3.7.3selenium 3.141.0

HTML:

<a href="javascript:GoPDF('FS1546')" style="TEXT-DECORATION: Underline">Aberdeen Standard Wholesale Australian Fixed Income</a>

代码:

from selenium import webdriver
driver = webdriver.Chrome("chromedriver.exe")
driver.get("http://www.colonialfirststate.com.au/Price_performance/performanceNPrice.aspx?menutabtype=performance&CompanyCode=001&Public=1&MainGroup=IF&BrandName=FC&ProductIDs=91&Product=FirstChoice+Wholesale+Investments&ACCodes=&ACText=&SearchType=Performance&Multi=False&Hedge=False&IvstType=Investment+products&IvstGroup=&APIR=&FundIDs=&FundName=&FundNames=&SearchProdIDs=&Redirect=1")
print(driver.find_elements_by_xpath("tbody/tr[5]/td[1]/a")

我需要的目标URL为:

  

https://www3.colonialfirststate.com.au/content/dam/prospects/fs/1/5/fs1546.pdf?3

但它给了我

  

javascript:GoPDF('FS2311')

2 个答案:

答案 0 :(得分:3)

我从弹出窗口中检查了PDF网址,并发现它们是如何生成URL的。

他们使用文件名(例如FS2065)生成PDF URL。

PDF的网址如下所示,        https://www3.colonialfirststate.com.au/content/dam/prospects/fs/2/0/fs2065.pdf?3

对于此部分之前的所有PDF,它都具有相同的路径

https://www3.colonialfirststate.com.au/content/dam/prospects/

在那部分之后,我们有一个使用fileID生成的路径,

fs/2/0/fs2065.pdf?3
 | | |     |     ||
 | | |     |     ++--- Not needed (But you can keep if you want)
 | | |     |
 | | |     +---- File Name
 | | +---------- 4th character in the file name 
 | +------------ 3rd character in the file name 
 +-------------- First two characters in the file name 

我们可以将其用作获取确切网址的解决方法。

url = "javascript:GoPDF('FS2311')" # javascript URL  

pdfFileId = url[18:-2].lower() # extracts the file name from the Javascript URL

pdfBaseUrl = "https://www3.colonialfirststate.com.au/content/dam/prospects/%s/%s/%s/%s.pdf?3"%(pdfFileId[:2],pdfFileId[2],pdfFileId[3],pdfFileId) 

print(pdfBaseUrl)
# prints https://www3.colonialfirststate.com.au/content/dam/prospects/fs/2/3/fs2311.pdf?3

查看实际情况here

答案 1 :(得分:0)

accepted answer进行后台工作表示敬意。

我建议使用标准库中的urllib.parse工具。 URL并不像它们最初出现时那么简单,写urllib的人是URL标准RFC 808的专家。

由于您正在抓取网页,因此,很可能需要对多个URL应用相同的过程,包括具有不同域名,多位数查询组件(?1234以及其他可能性)甚至片段(?1234#example等。)接受的答案在所有这些答案上都会失败。

以下代码乍看之下似乎更加复杂,但是将棘手的(可能是脆弱的)URL委托给了urllib。它还使用更健壮和灵活的方法来提取GoPDF fileId和url的不变部分。

from urllib.parse import urlparse, urlunparse


def build_pdf_url(model_url, js_href):
    url = urlparse(model_url)
    pdf_fileid = get_fileid_from_js_href(js_href)
    pdf_path = build_pdf_path(model_url, pdf_fileid)
    return urlunparse((url.scheme, url.netloc, pdf_path, url.params,
                      url.query, url.fragment))


def get_fileid_from_js_href(href):
    """extract fileid by extracting text between single quotes"""
    return href.split("'")[1].lower()


def build_pdf_path(url, pdf_fileid):
    prefix = pdf_fileid[:2]
    major_version = pdf_fileid[2]
    minor_version = pdf_fileid[3]
    filename = pdf_fileid + '.pdf'
    return '/'.join([invariant_path(url), prefix, major_version, minor_version, filename])


def invariant_path(url, dropped_components=4):
    """
    return all but the dropped components of the URL 'path'
    NOTE: path components are separated by '/'
    """
    path_components = urlparse(url).path.split('/')
    return '/'.join(path_components[:-dropped_components])


js_href = "javascript:GoPDF('FS1546')"
model_url = "https://www3.colonialfirststate.com.au/content/dam/prospects/fs/2/3/fs2311.pdf?3"
print(build_pdf_url(model_url, js_href))


$ python urlbuild.py
https://www3.colonialfirststate.com.au/content/dam/prospects/fs/1/5/fs1546.pdf?3