2016-07-25 7 views
1

私はウェブサイトからデータをスクレイピングする練習をしています。たとえば、ZocDocです。私はすべての保険業者とその計画のリストを取得しようとしています(あなたは保険のドロップダウンでホームページにこの情報にアクセスできます)。スクラップウェブページは作成されていませんが、DOMにはデータはありません

ページが読み込まれると、すべてのデータが<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に保険プランはありません。また、計画が戻ってきたネットワークタブには要求が表示されません(バックボーンファイルがいくつかあります)。 1つのURLがエンコードされているように見えますが、それはそれであると私は確信していません。私はちょうどこれを思っています。url

私はまた、すべてのJSがロードされるのを待って、dryscrapeを使用してデータがDOM内にあるようにしましたが、HTMLにはまだ計画はありません。

クローラが各保険会社をクリックして計画を立てることなく、この情報を収集する方法はありますか?

+0

あなたが投稿したURLはエンコードされています。これは単にテキストの序数です。情報内の外側の 'eval 'を' console.log'に変更することで戻すことができます。それはより多くの機能を返すでしょう。最後に 'eval( 'String.fromCharCode(' + z + '))の代わりに' console.log(eval(' String.fromCharCode( '+ z +') '));}) '));})() ' –

+0

@CoryShayそれを指摘してくれてありがとう。それはクッキーのように見える – user2954587

答えて

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コードの素晴らしい世界に飛び込むがslimitのような正規表現またはJavaScriptパーサのいずれかPythonで解析することができます(example here)、これは頭部の毛が少なくなることがあります。さらに、結果のソリューションは非常に壊れやすいでしょう。

この特定のケースでは、私は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() 

プリント:この場合には、ヘッドレスPhantomJSブラウザが使用されていることを

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

ますが、あなたはセレンが持っているクロムまたはFirefoxや他のブラウザを使用することができますのための利用可能なドライバ。

+0

はい、私は保険会社を得ることができますが、計画の名前はありません。それらのプロバイダのそれぞれにも計画があります。それが私が問題を抱えているのです – user2954587

+0

例計画は 'ActiveCare 2' – user2954587

+0

@ user2954587 gotchaです。これは、保険をクリックして計画を抽出する必要があります。私は何かを考えて後で更新します。ありがとう。 – alecxe

関連する問題