抓取网页没有进行ajax调用,但数据不在DOM

时间:2016-07-25 22:42:48

标签: javascript python web-scraping

我正在从网站上抓取数据。例如,ZocDoc。我试图获取所有保险提供商及其计划的清单(您可以在保险下拉列表中访问其主页上的此信息)。

当页面加载时,似乎所有数据都通过<scipt>标记加载。查看网络选项卡时,似乎没有任何返回JSON的网络调用,包括计划名称。我可以使用以下内容获得所有保险计划(这很麻烦,但它确实有效)。

  import requests
  from bs4 import BeautifulSoup as bs
  resp = requests.get('https://zocdoc.com')
  long_str = str(soup.findAll('script')[17].string)
  pop = data.split("Popular Insurances")[1]
  json.loads(pop[pop.find("[["):pop.find("]]")+2])

在返回的HTML中没有保险计划。我也没有在网络选项卡中看到任何发送计划的请求(有一些主干文件)。一个网址看起来已编码,但我不确定是不是这样,我只是过度思考这个url

我还尝试等待所有JS加载,因此数据使用dryscrape在DOM中,但HTML中仍然没有计划。

有没有办法收集这些信息,而无需抓取每个保险提供商的抓取工具来获取他们的计划?

1 个答案:

答案 0 :(得分:2)

是的,保险清单深入script标签:

insuranceModel = new gs.CarrierGroupedSelect(gs.CarrierGroupedSelect.prototype.parse({
...
primary_options: {
        name: "Popular Insurances",
        group: "primary",
        options: [[300,"Aetna",2,0,1,0],[304,"Blue Cross Blue Shield",2,1,1,0],[307,"Cigna",2,0,1,0],[369,"Coventry Health Care",2,0,1,0],[358,"Medicaid",2,0,1,0],[322,"UniCare",2,0,1,0],[323,"UnitedHealthcare",2,0,1,0]]
    },
    secondary_options: {
        name: "All Insurances",
        group: "secondary",
        options: [[440,"1199SEIU",2,0,1,0],[876,"20/20 Eyecare Plan",2,0,1,1],...]
    }
...

当然,您可以使用正则表达式或Javascript解析器(如slimitexample here)深入了解Python中JavaScript代码解析的精彩世界,但这可能会减少头部的毛发。此外,结果解决方案将非常脆弱。

在这种特殊情况下,我认为selenium更适合。完整的工作示例 - 获得流行的保险:

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


driver = webdriver.PhantomJS()
driver.maximize_window()

wait = WebDriverWait(driver, 10)
insurance_dropdown = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "I'll choose my insurance later")))
insurance_dropdown.click()

for option in driver.find_elements_by_css_selector("[data-group=primary] + .ui-gs-option-set > .ui-gs-option"):
    print(option.get_attribute("data-value"))

driver.close()

打印:

Aetna
Blue Cross Blue Shield
Cigna
Coventry Health Care
Medicaid
UniCare
UnitedHealthcare

请注意,在这种情况下,会使用无头PhantomJS浏览器,但您可以使用Chrome或Firefox或其他selenium具有可用驱动程序的浏览器。