【问题标题】:Can't get javascript generated html using python & Selenium webdriver无法使用 python 和 Selenium webdriver 获取 javascript 生成的 html
【发布时间】:2018-11-18 17:23:24
【问题描述】:

我正在尝试使用以下 Python 代码从链接中获取培训列表:

from selenium import webdriver
url = 'https://www.cbtnuggets.com/search'
browser = webdriver.Chrome()
browser.get(url)
browser.implicitly_wait(30)
print(browser.find_element_by_tag_name("table").text)
browser.quit()

大多数情况下,我只是将表头作为输出:

课程名称培训师评级供应商 IT 路径技能水平

但是这个输出并不一致,一两次(在 20 次尝试中)打印了整个表格(列出了网页中的所有培训),但我无法获得一致的输出。

我在 30-60 秒之间调整了 implicitly_wait(30) 但没有解决。我还可以看到 AJAX 内容在 30 秒计时器内加载良好。

我的要求:

  1. 获取培训列表
  2. 还将每个培训页面的超链接添加到另一列中。例如表中的第一个培训有链接https://www.cbtnuggets.com/it-training/isc2-cissp-2015

所以输出应该有以下表格标题

  • 课程名称
  • 培训师
  • 评分
  • 供应商
  • IT 路径
  • 技能水平
  • 课程网址(从href标签中提取)

【问题讨论】:

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


    【解决方案1】:

    试试这个以获得所需的内容。无论您是否等待获得表格,它总是与标题一起存在。但是,tbody 内容是动态生成的,因此您应该让脚本等待它可用。

    from selenium import webdriver
    
    url = 'https://www.cbtnuggets.com/search'
    
    browser = webdriver.Chrome()
    browser.get(url)
    browser.implicitly_wait(30)
    for items in browser.find_elements_by_css_selector("table tbody tr"):
        data = [item.get_attribute("href") for item in items.find_elements_by_css_selector("a")]
        print(data)
    browser.quit()
    

    为了加快执行时间,您可以将BeautifulSoupselenium 结合使用,如下所示:

    from bs4 import BeautifulSoup
    from selenium import webdriver
    
    url = 'https://www.cbtnuggets.com/search'
    
    driver = webdriver.Chrome()
    driver.get(url)
    driver.implicitly_wait(30)
    table = driver.find_elements_by_css_selector("table tbody")
    soup = BeautifulSoup(driver.page_source,"lxml") #if you haven't installed "lxml" yet, try replacing it with "html.parser"
    for items in soup.select("table tbody tr"):
        data = [item.get("href") for item in items.select("a")]
        print(data)
    driver.quit()
    

    【讨论】:

    • 谢谢。这确实显示了 tbody 内容,但是,我如何获得每个培训页面的网页链接?
    【解决方案2】:

    您可以通过重新创建在页面上发出的 XHR API 请求(检索目录信息)并处理 JSON 响应来做到这一点。我欢迎有关如何删除data 上的重复循环的建议。我曾考虑在单个循环中使用解包,但认为即使确实有效,也很难遵循。但是,它仍然很快。

    import requests
    import pandas as pd
    
    base = 'https://www.cbtnuggets.com/it-training/' 
    response  = requests.get('https://api.cbtnuggets.com/site-gateway/v1/all/courses/for/search?archive=false')
    data = response.json()
    titles = [item['title'] for item in data]
    trainers = [item['trainers'][0]['name'] for item in data]
    ratings = [item['rating'] for item in data]
    vendors = [item['vendors'][0]['display'] if len(item['vendors']) != 0 else 'N/A' for item in data]
    paths = [item['paths'][0]['path_label'] for item in data]
    skillLevel = [item['difficulty']['display'] for item in data]
    links = [base + item['seoslug'] for item in data]
    
    df=  pd.DataFrame(
        {'Course Title': titles,
         'Trainer': trainers,
         'Rating': ratings,
         'Vendor': vendors,
         'IT Path': paths,
         'Skill Level': skillLevel,
         'Course URL': links
        })
    
    print(df)
    df.to_csv(r'C:\Users\User\Desktop\Data.csv', sep=',', encoding='utf-8',index = False )
    

    【讨论】:

      猜你喜欢
      • 2017-10-04
      • 2017-02-04
      • 2014-02-22
      • 2013-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 2018-03-03
      相关资源
      最近更新 更多