ホームページ  >  記事  >  バックエンド開発  >  Mobike クローラーのソースコード分析

Mobike クローラーのソースコード分析

PHPz
PHPzオリジナル
2017-04-04 10:40:342475ブラウズ

最初の 2 つの記事では、Mobike の インターフェイス を取得した理由とデータ分析の結果を分析しました。この記事では、Zhongjiao が実行可能ソースを直接提供しています学習用のコードです。

声明:
このクローラーは学習と研究目的のみに使用してください。

記事を読んだ場合は、直接ご連絡ください。気に入ったらスターを付けることを忘れないでください!

ディレクトリ構造

    analysis - データ分析用の jupyter - influxdb にインポートします。
  • module

    s - プロキシモジュール

  • web - 当時はreactを学ぶためのものでした

  • crawler.py - crawler corecode

  • importtodb.py-分析用のpostgresデータベースにインポート
  • sql.sql -create tablesql
  • start.sh-継続的に実行されていますcoreコードコードはですは、crawler.py に配置され、データは最初に
  • sqlite

    3 データベースに保存され、スペースを節約するために重複排除後に CSV ファイルにエクスポートされます。自転車の場合、

  • Mobike の
  • API

    は正方形の領域を返します。

  • 左、

をエリアごとに移動して、広いエリア全体のデータを作成します。これは、現在の成都環状高速道路内と南湖までの広場エリアです。 off

set

はクロール間隔を定義しており、現在は 0.002 に基づいており、DigitalOcean 5$ サーバー

git clone https://github.com/derekhe/mobike-crawler
python3 crawler.py

で 15 分に 1 回クロールできます。なぜですか。私はコルーチンを使用しませんでした、ハミング~~当時は習いませんでした~~~実際には可能です、おそらくより効率的です 小さな正方形領域間の重複を削除するには、データを取得した後に処理する必要があるためです。最後の group_data はまさにこれを行います

    def start(self):
        left = 30.7828453209
        top = 103.9213455517
        right = 30.4781772402
        bottom = 104.2178123382

        offset = 0.002

        if os.path.isfile(self.db_name):
            os.remove(self.db_name)

        try:
            with sqlite3.connect(self.db_name) as c:
                c.execute('''CREATE TABLE mobike
                    (Time DATETIME, bikeIds VARCHAR(12), bikeType TINYINT,distId INTEGER,distNum TINYINT, type TINYINT, x DOUBLE, y DOUBLE)''')
        except Exception as ex:
            pass
コア API コードは、いくつかの 変数を作成するだけです

        executor = ThreadPoolExecutor(max_workers=250)
        print("Start")
        self.total = 0
        lat_range = np.arange(left, right, -offset)
        for lat in lat_range:
            lon_range = np.arange(top, bottom, offset)
            for lon in lon_range:
                self.total += 1
                executor.submit(self.get_nearby_bikes, (lat, lon))

        executor.shutdown()
        self.group_data()
最後に、Mobike はブロックされているかどうかを尋ねたいかもしれません。 IP アクセス速度の制限がありますが、それを解決する方法は、多数のプロキシ を使用することです。私は基本的に毎日 8,000 を超えるプロキシ プールを持っており、ProxyProvider でこのプロキシ プールを直接取得し、ピック機能を提供します。 上位 50 のプロキシをランダムに選択します。プロキシ プールは 1 時間ごとに更新されます

が、コードで提供されている

json

blob プロキシ リストは単なるサンプルであり、しばらくするとそのほとんどが無効になることに注意してください。

ここでは代理スコアリングメカニズムが使用されます。エージェントを直接ランダムに選択するのではなく、スコアに従ってエージェントを並べ替えました。リクエストが成功するとポイントが追加され、リクエストが失敗するとポイントが減点されます。これにより、最適なスピードと品質を備えたエージェントを短時間で選択することができます。保存しておいて、必要に応じて次回使用することができます。

    def get_nearby_bikes(self, args):
        try:
            url = "https://mwx.mobike.com/mobike-api/rent/nearbyBikesInfo.do"

            payload = "latitude=%s&longitude=%s&errMsg=getMapCenterLocation" % (args[0], args[1])

            headers = {
                'charset': "utf-8",
                'platform': "4",
                "referer":"https://servicewechat.com/wx40f112341ae33edb/1/",
                'content-type': "application/x-www-form-urlencoded",
                'user-agent': "MicroMessenger/6.5.4.1000 NetType/WIFI Language/zh_CN",
                'host': "mwx.mobike.com",
                'connection': "Keep-Alive",
                'accept-encoding': "gzip",
                'cache-control': "no-cache"
            }

            self.request(headers, payload, args, url)
        except Exception as ex:
            print(ex)
実際に使用する場合は、proxyProvider.pick()でプロキシを選択して使用します。プロキシに問題がある場合は、proxy.fatal_error() を直接使用してスコアを下げ、今後このプロキシが選択されないようにします。

class ProxyProvider:
    def init(self, min_proxies=200):
        self._bad_proxies = {}
        self._minProxies = min_proxies
        self.lock = threading.RLock()

        self.get_list()

    def get_list(self):
        logger.debug("Getting proxy list")
        r = requests.get("https://jsonblob.com/31bf2dc8-00e6-11e7-a0ba-e39b7fdbe78b", timeout=10)
        proxies = ujson.decode(r.text)
        logger.debug("Got %s proxies", len(proxies))
        self._proxies = list(map(lambda p: Proxy(p), proxies))

    def pick(self):
        with self.lock:
            self._proxies.sort(key = lambda p: p.score, reverse=True)
            proxy_len = len(self._proxies)
            max_range = 50 if proxy_len > 50 else proxy_len
            proxy = self._proxies[random.randrange(1, max_range)]
            proxy.used()

            return proxy

わかりました、基本的にはこれです~~~他のコードは自分で勉強してください~~~

以上がMobike クローラーのソースコード分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。