2016-04-05 6 views
2

私はコースの名前をUdacityから学生の人数でスクラップして、どのコースが最も人気があるのか​​を調べようとしています。私はアイテムのコードを作成するために管理します。私はもちろんの名前を取得していますが、代わりに学生数の私はのテキスト」数千人を取得していた結果インタラクティブウェブサイトを掻き立てる

import scrapy 
from Udacity.items import UdacityItem 
import re 

class DmozSpider(scrapy.Spider): 
    name = "UdSpider" 
    allowed_domains = ["udacity.com"] 
    start_urls = ["https://www.udacity.com/courses/all"] 

    def parse(self, response): 

     sites = response.xpath('//h3/a') 
     for s in sites: 
      t=UdacityItem() 
      #name & url 
      t['name']=s.xpath('text()').extract()[0].strip() 
      url=response.urljoin(s.xpath('@href').extract()[0]) 
      #request 
      req=scrapy.Request(url, callback=self.second) 
      req.meta['item']=t 
      #execute 
      yield req 

    def second(self,response): 
     t=response.meta['item'] 
     strong =response.xpath('//strong[@data-course-student-count]/text()').extract()[0] 
     t['users']=strong 
     yield t 

import scrapy 
class UdacityItem(scrapy.Item): 
    name=scrapy.Field() 
    users=scrapy.Field() 

とクモ'ブラウザでexample websiteを開くと、「千の」が基本値であり、後で(1〜2秒で)このテキストが適切な数値(私が取得したい)に変化していることがわかります。なぜ、この置換が起こっている

  1. そして、ここでは私の質問ですか?このJavaScriptコードですか?私は この変更の仕組みを理解したいと思います。

  2. 私はスクレイピーを使用して適切な人数をどのように獲得できますか?私はこれが可能であることを望む。

ありがとうございました。

答えて

2

登録数を取得するには、https://www.udacity.com/course/javascript-promises--ud898 URLの場合はud898など、URL自体から抽出できる特定のコースIDの場合、https://www.udacity.com/api/summariesエンドポイントへのAPIリクエストをシミュレートする必要があります。

完全なクモ:

import json 

import re 
from urllib import quote_plus 

import scrapy 


class UdacityItem(scrapy.Item): 
    name = scrapy.Field() 
    users = scrapy.Field() 


class DmozSpider(scrapy.Spider): 
    name = "UdSpider" 
    allowed_domains = ["udacity.com"] 
    start_urls = ["https://www.udacity.com/courses/all"] 

    def parse(self, response): 
     sites = response.xpath('//h3/a') 
     for s in sites: 
      t = UdacityItem() 
      # name & url 
      t['name'] = s.xpath('text()').extract()[0].strip() 
      url = response.urljoin(s.xpath('@href').extract()[0]) 
      # request 
      req = scrapy.Request(url, callback=self.second) 
      req.meta['item'] = t 
      # execute 
      yield req 

    def second(self, response): 
     queries = [{ 
      "limit": 1, 
      "model": "CourseStudentsSummary", 
      "locator": { 
       "sample_frequency": "daily", 
       "content_context": [{ 
        "node_key": re.search(r'--(.*?)$', response.url).group(1) 
       }] 
      } 
     }] 
     yield scrapy.Request(method="GET", 
          url="https://www.udacity.com/api/summaries?queries=" + quote_plus(json.dumps(queries)), 
          callback=self.parse_totals) 

    def parse_totals(self, response): 
     print(json.loads(response.body[5:].strip())["summaries"]["default"][0]["data"]["total_enrollments"]) 
+0

親愛なるalecxe。返信してくれてありがとう。今私は解決策がありますが、私はまだHTMLの読み込みとAPIリクエストの送信との間のリンクは見られません。文書を見ると、そのコードを見つけることができません。 APIリクエストを行う必要があることをどのように理解していますか?私はJavaScriptコードがドキュメントの最後にロードされているコードに責任があると思いますか? – michalk

+1

@michalk私はブラウザの開発ツールを使っています - ネットワークタブとフィルタされたXHRリクエストのみ。ページの読み込み中にいくつかのXHRリクエストがあり、それらを調べてレスポンス内のトータルの登録を見つけました。次に、Scrapy..hopeで同じリクエストを作成するのに役立ちました。 – alecxe

関連する問題