2016-12-29 9 views
0

ウェブサイトのホームページとホームページにある内部リンクを訪問する簡単なパーサーを作成しました。基本的には、ホームページから始まるウェブサイト構造に1レベル深く入り、正規表現に一致する文字列を検索します。それはJSを実行するalo。電子メール、電話番号、または整形されたデータのどんなものでも動作します。私はしばらくの間、このスクレーパーを走った、そして、それは信じられないほど遅いですtraverseHomePage("http://homepage.com")ウェブスクレイパーは数秒ごとにウェブサイトを取得します

:使用方法の

pages = set() 
def getPage(startUrl): 
    user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11' 
    dcap = dict(DesiredCapabilities.PHANTOMJS) 
    dcap["phantomjs.page.settings.userAgent"] = (user_agent) 

    driver = webdriver.PhantomJS(executable_path="/Users/mainuser/Downloads/phantomjs-2.1.1-macosx/bin/phantomjs", desired_capabilities=dcap) 
#  print("in get page: "+startUrl) 
    try: 
     driver.set_page_load_timeout(10) 
     driver.get(startUrl) 
     return BeautifulSoup(driver.page_source,"html.parser") 
    except: 
     print("returning NOne") 
     return None 

def traverseHomePage(startUrl): 

    if startUrl.endswith("/"): 
     startUrl = startUrl[:-1] 
    try: 
     driver = webdriver.PhantomJS(executable_path="/Users/mainuser/Downloads/phantomjs-2.1.1-macosx/bin/phantomjs") 
     driver.get(startUrl) 
    except HTTPError as e: 
     print(e) 
#   print(pageUrl+" ") 
     pass 
    except URLError as e: 
     print(e) 
     pass 
    else: 

     bsObj = BeautifulSoup(driver.page_source,"html.parser") 

     text = str(bsObj) 
     listRegex = re.findall(r'someregexhere', text) 
     print(listRegex+" do something with data") 


     for link in bsObj.findAll("a", href=re.compile("^((?!#|javascript|\.png|\.jpg|\.gif).)*$")): 
      if 'href' in link.attrs: 

       if ("http://" in link.attrs['href'] or "https://" in link.attrs['href']) and startUrl in link.attrs['href']: 
        print("internal aboslute: "+startUrl+" is in "+link.attrs['href']) 
        #absolute link 
        if 'href' in link.attrs: 
         if link.attrs['href'] not in pages: 
          #We have encountered a new page 
          newPage = link.attrs['href'] 
          oneLevelDeep(newPage) 

       elif ("http://" in link.attrs['href'] or "https://" in link.attrs['href'] or "mailto" in link.attrs['href']) and (startUrl not in link.attrs['href']): 
        print("outside link"+link.attrs['href']) 
#      print(link.attrs['href']) 
        continue 
       else: 
        print("internal relative: "+link.attrs['href']) 
        #relative link 
        if 'href' in link.attrs: 
         if link.attrs['href'] not in pages: 
            #We have encountered a new page 
            newPage = link.attrs['href'] 
            pages.add(newPage) 

            if newPage.startswith("/"): 
             pass 
      #        print("/"+newPage) 
            else: 
             newPage = "/"+newPage 
            pages.add(newPage) 
            oneLevelDeep(startUrl+newPage) 

def oneLevelDeep(startUrl): 
#  print(startUrl) 
    if startUrl.endswith("/"): 
     startUrl = startUrl[:-1] 

    try: 
#   print("stUrl: "+startUrl+pageUrl) 
     bsObj = getPage(startUrl) 
     if bsObj != "None": 
      text = str(bsObj) 

      text = str(bsObj) 
     listRegex = re.findall(r'someregexhere', text) 
     print(listRegex+" do something with data") 
#   
    except HTTPError as e: 
#   print(e) 
#   print(pageUrl+" ") 
     pass 
    except URLError as e: 
#   print(e) 
     pass 

例:これはコードです。 Eclipseで8回プロジェクトをコピーしても、12時間で1000ページしか検索できませんでした。私は真剣に1日あたり250ページだけGoogleのボットのインデックスを疑う。

ボトルネックは、1分あたりのボットのリクエストページ数です。それは数秒ごとに1つずつです。私は毎秒50リクエストを行うボットについて読んだことがあります。これはこのケースでは当てはまりません。

スクレイピングの速度を向上させるにはどうすればよいですか? Eclipse localhostからコードを実行しています。私がサーバーに移動すると、それは役に立ちますか?私は何とかサーバーに画像を送らないように指示しなければならないので、帯域幅を少なくしますか?非同期要求を行うことは可能ですか?複数のスクリプトが同時に非同期で実行されていますか?どんなアイディアも大歓迎です。

答えて

1

問題は、ブラウザがページにアクセスするようにWebページを読み込んでいることです。あなたがhomepage.comを開き、開発者メニューに行き、次にネットワークに入ったら(少なくともクロムで)、このページが読み込まれるまでに時間がかかることがわかります。私の場合、最後のファイルがGoogleマップの認証ファイルであることと一緒に7秒かかりました。

グーグルでは、解析を実行するサーバーがサーバー上にあり、ルートディレクトリからいくつかのファイルだけが検索されるため、そのページのすべてのリンクと後続の各ページのすべてのリンクそれ。ページ全体が読み込まれるのを待つ必要はありません。各サイトの生のhtmlだけが必要です。

JavaScriptを待っていて、サイト全体をダウンロードすると、(1つのhtmlファイルではなく)cssとすべてが検索の速度を落としています。私は裸のhtmlを取得し、そこから作業する要求を使用します。

+0

ありがとうございます。動的データを検索することが多いため、JSを解析から除外するオプションはありません。 htmlとjsだけをダウンロードする方法に関するいくつかのコードを提供できますか? – sanjihan

+0

あなたが動的と言うときは実行時に生成されるか、おそらくJavaScriptファイルであらかじめ決められていますか? – arlyon

+0

要求モジュールを使用すると、Webページのhtmlを簡単にダウンロードできます.jsファイルやその他のリンクを検索して、キューに追加することができます。 – arlyon

関連する問題