Flexテクノロジーに基づいてWebサイトをクロールする方法

 

Adobe FlexはFlashプラットフォームに基づいており、RIA(Rich Internet Applications)の開発と展開をサポートする一連のテクノロジーの組み合わせをカバーしています。多くのWebベースのオンラインゲームは、Flexテクノロジーを使用して開発されています。

Flash(クライアント)とサーバー間の通信は、HTTPプロトコル(特定のテキストメッセージ形式はテキスト、XML、JSON、AMFなど)と元のソケットの両方をサポートし、HTTPプロトコルがより一般的です。

テキスト、XML、またはJSONメッセージ形式を使用するFlexアプリケーションの場合、分析およびクロールの方法は、AjaxベースのWebサイトの場合と同じです。

HTTPプロトコルキャプチャツール(Fiddler、Firebugなど)を使用してリクエストの構造(リクエストメソッド、URL、関連パラメータ)とステップを分析し、プログラムを使用して同じ形式でリクエストをシミュレートし、返されたデータを分析して抽出します。

この記事では、主にAMFメッセージ形式を使用したFlexアプリケーションのキャプチャ方法を紹介します。例として「中国農産物卸売市場情報広報システム」(以下「農産物システム」という)を例にとると、そのURLはhttp://jgsb.agri.gov.cn/flexapps/hqApp.swfです。私たちの目標は、このシステムを取り込むことです。リアルタイムで公開されている最新の農産物価格情報。

AMF(Action Message Format、https://en.wikipedia.org/wiki/Action_Message_Format)は、Flashとサーバー間の通信に一般的なバイナリエンコードモードであり、送信効率が高く、HTTPレベルで送信できます。現在、多くのFlashWebGamesがこのメッセージ形式を使用しています。

Fidderを直接使用してAMFパッケージをキャプチャできますが、表示されるPOST DATA本体は文字化けした形式です。これは、AMFが特別なカプセル化とエンコードの方法を使用しているためです。正しいAMFのデコードと解析を行った後にのみ、「プレーンテキスト」を表示できます。形。現在、AMF解析をサポートするキャプチャツールはCharlesです(Fiddlerと同様に、HTTP PROXYの原理に基づくHTTPプロトコルキャプチャツールでもあります)。追加のプラグインやパッチをインストールせずに、AMFメッセージの解析をネイティブにサポートします。

分析手順は次のとおりです。

1)チャールズを起動します。

2)ブラウザの「農産物システム」にアクセスし、次のページをクリックしてください。

3)Charlesで対応するデータパケットを確認し、[AMF]タブに切り替えると、要求/応答AMFデータがプレーンテキスト(JSON形式と同様)に解析されていることがわかります。要求データと応答データをAMF形式で分析し、その構造と各パラメーターの意味を理解して、将来のプログラムの実現に備えます。

次の図に示すように、これはHTTPリクエストのPOSTDATAです。

Charles解æåºæ¥çAMFæ°æ®

リクエストのパラメータの意味とメッセージの構造を分析する必要があります。本文部分はRemotingMessageタイプのメッセージであり、メッセージの本文には3つのパラメーターがあります。

a)最初のパラメーターはcom.itown.kas.pfsc.report.po.HqParaオブジェクトで、4つの属性(marketInfo、breedInfoDl、breedInfo、province)があり、値はすべてNullで、Webページ(Flash)に対応します4つのクエリオプション(州、市場、カテゴリ、カテゴリ名)。

b)2番目のパラメーターは、現在のページ番号を制御します。

c)3番目のパラメーターは、各ページに表示されるバーの数を制御します。デフォルトは15です。後でコレクションコードで50を使用します。

他の重要ではないパラメータと応答データの分析プロセスをスキップします。

PyAMFは、AMFプロトコルエンコーダーおよびデコーダーのPython実装です。このプロジェクトの公式ウェブサイトにアクセスできなくなったこと、および上記のドキュメントとサンプルプログラムを表示できなくなったことは残念です。これにより、開発が大幅に困難になります。幸いなことに、Google(Baiduではなく)を通じて、他の人のプロジェクトで使用されている参考資料や例を見つけることができます。

ソースコードはすぐ下にあります:

# coding: utf-8
# agri.gov.cn_amf_client.py
# http://jgsb.agri.gov.cn/flexapps/hqApp.swf数据抓取
# refer: http://www.site-digger.com/html/articles/20160418/121.html  

import urllib2
import uuid
import pyamf
from pyamf import remoting
from pyamf.flex import messaging
from urllib.request import Request, urlopen

class HqPara:
    """查询参数
    """
    def __init__(self):
        self.marketInfo = None
        self.breedInfoDl = None
        self.breedInfo = None
        self.provice = None
# https://en.wikipedia.org/wiki/Action_Message_Format
# registerClassAlias("personTypeAlias", Person);
# 注册自定义的Body参数类型,这样数据类型com.itown.kas.pfsc.report.po.HqPara就会在后面被一并发给服务端(否则服务端就可能返回参数不是预期的异常Client.Message.Deserialize.InvalidType)
pyamf.register_class(HqPara, alias='com.itown.kas.pfsc.report.po.HqPara')

# 构造flex.messaging.messages.RemotingMessage消息
msg = messaging.RemotingMessage(messageId=str(uuid.uuid1()).upper(),
                                clientId=str(uuid.uuid1()).upper(),
                                operation='getHqSearchData',
                                destination='reportStatService',
                                timeToLive=0,
                                timestamp=0)
# 第一个是查询参数,第二个是页数,第三个是控制每页显示的数量(默认每页只显示15条)
msg.body = [HqPara(), '1', '50']
msg.headers['DSEndpoint'] = None
msg.headers['DSId'] = str(uuid.uuid1()).upper()
# 按AMF协议编码数据
req = remoting.Request('null', body=(msg,))
env = remoting.Envelope(amfVersion=pyamf.AMF3)
env.bodies = [('/1', req)]
data = bytes(remoting.encode(env).read())

# 提交请求
url = 'http://jgsb.agri.gov.cn/messagebroker/amf'
headers = {'Content-Type': 'application/x-amf', 'Host': 'jgsb.agri.cn'}
# req = urllib.request.urlopen(url, data, headers={'Content-Type': 'application/x-amf', 'Host': 'jgsb.agri.cn'})

req = Request(url, data=data, headers=headers)

# 解析返回数据
req_data = urlopen(req).read()

# 解码AMF协议返回的数据
resp = remoting.decode(req_data)
for i, record in enumerate(resp.bodies[0][1].body.body[0]):
    print i, record['farmProduceName'], \
          record['marketName'], \
          record['maxPrice'], \
          record['minPrice'], \
          record['averagePrice'], \
          record['producAdd'] and record['producAdd'], \
          record['reportMan']

 実行結果のスクリーンショット:

åºäºFlexAMFææ¯ç½ç«æåç¨åºè¿è¡ç»æ

特記事項:この記事は技術交流のためのものです。関連する技術を違法な目的で使用しないでください。使用しないと、すべての結果が発生します。当社がお客様の法的権利を侵害していると思われる場合は、当社にご連絡ください。 

おすすめ

転載: blog.csdn.net/someby/article/details/108651516
おすすめ