最初の 2 つの記事では、Mobike の インターフェイス を取得した理由とデータ分析の結果を分析しました。この記事では、Zhongjiao が実行可能ソースを直接提供しています学習用のコードです。
声明:
このクローラーは学習と研究目的のみに使用してください。
記事を読んだ場合は、直接ご連絡ください。気に入ったらスターを付けることを忘れないでください!
ディレクトリ構造s - プロキシモジュール
web - 当時はreactを学ぶためのものでした
3 データベースに保存され、スペースを節約するために重複排除後に CSV ファイルにエクスポートされます。自転車の場合、
は正方形の領域を返します。
、下をエリアごとに移動して、広いエリア全体のデータを作成します。これは、現在の成都環状高速道路内と南湖までの広場エリアです。 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 時間ごとに更新されます
が、コードで提供されている
jsonblob プロキシ リストは単なるサンプルであり、しばらくするとそのほとんどが無効になることに注意してください。
ここでは代理スコアリングメカニズムが使用されます。エージェントを直接ランダムに選択するのではなく、スコアに従ってエージェントを並べ替えました。リクエストが成功するとポイントが追加され、リクエストが失敗するとポイントが減点されます。これにより、最適なスピードと品質を備えたエージェントを短時間で選択することができます。保存しておいて、必要に応じて次回使用することができます。 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 サイトの他の関連記事を参照してください。