0

中国のマイクロブログ Sina Weibo からリツイート データを収集しようとしています。次のコードを参照してください。ただし、IP リクエストが制限を超えているという問題に苦しんでいます。

この問題を解決するには、コードに time.sleep() を設定する必要があります。コードに「time.sleep(10) # to opress the ip request limit」という行を追加しようとしたことがわかります。したがって、Python はリツイートのページをクロールした後、10 秒間スリープします (1 ページには 200 件のリツイートが含まれます)。

しかし、知的財産の問題に​​対処するにはまだ十分ではありません。

したがって、20ページごとにクロールした後、pythonをより体系的に60秒スリープさせることを計画しています。あなたのアイデアは高く評価されます。ID=[3388154704688495, 3388154704688494, 3388154704688492]

        addressForSavingData= "C:/Python27/weibo/Weibo_repost/repostOwsSave1.csv"    
        file = open(addressForSavingData,'wb') # save to csv file 

        for id in ids:
            if api.rate_limit_status().remaining_hits >= 205:  
                for object in api.counts(ids=id):
                    repost_count=object.__getattribute__('rt')
                    print id, repost_count
                    pages= repost_count/200 +2  # why should it be 2? cuz python starts from 0  
                    for page in range(1, pages):
                        time.sleep(10)  # to opress the ip request limit
                        for object in api.repost_timeline(id=id, count=200, page=page):  # get the repost_timeline of a weibo
                            """1.1 reposts"""
                            mid = object.__getattribute__("id")
                            text = object.__getattribute__("text").encode('gb18030')     # add encode here
                            """1.2 reposts.user"""
                            user = object.__getattribute__("user") # for object in user
                            user_id = user.id                                   
                            """2.1 retweeted_status"""
                            rts = object.__getattribute__("retweeted_status")
                            rts_mid = rts.id  # the id of weibo     
                            """2.2 retweeted_status.user"""
                            rtsuser_id = rts.user[u'id']                                                        
                            try:
                                w = csv.writer(file,delimiter=',',quotechar='|', quoting=csv.QUOTE_MINIMAL)
                                w.writerow(( mid,
                                            user_id, rts_mid,
                                            rtsuser_id, text)) # write it out   
                            except:  # Exception of UnicodeEncodeError
                                pass
            elif api.rate_limit_status().remaining_hits < 205:  
                sleep_time=api.rate_limit_status().reset_time_in_seconds # time.time()
                print sleep_time, api.rate_limit_status().reset_time
                time.sleep(sleep_time+2)
        file.close()
        pass
4

2 に答える 2

0

私は解決策を見つけます:

まず、0 などの整数を指定します

i = 0

次に、for ページ ループに次のコードを追加します。

for page in range(1, 300):
    i += 1
    if (i % 25 ==0):
        print i, "find i which could be exactly divided by 25"
于 2012-05-20T09:06:53.950 に答える
0

代わりに、スクリプトのペースを調整することはできませんか?

リクエストをすべて同時に行うのではなく、リクエストごとにスクリプトをスリープ状態にすることをお勧めします。そして、1 分以上スパンと言います。このようにして、フラッディング禁止も回避され、これは良い動作と見なされます。

サーバーがあまりにも多くのリクエストを送信してもタイムアウトしない場合は、リクエストのペースを調整することで、より迅速に処理を行うことができます。


IP に制限がある場合、優れた簡単な解決策ではない場合があります。たとえば、apache http://opensource.adnovum.ch/mod_qos/を実行すると、帯域幅と接続が制限され、具体的には制限されます。

  • 同時リクエストの最大数
  • URL への 1 秒あたりの最大許容リクエスト数や 1 秒あたりのダウンロードキロバイトの最大/最小数などの帯域幅の制限。
  • 1 秒あたりのリクエスト イベント数を制限します
  • 許可されていない操作を拒否するための一般的な要求行とヘッダー フィルター。
  • リクエスト本文データの制限とフィルタリング
  • 単一の IP ソース アドレスまたは動的キープアライブ制御から許可される接続の最大数。

あなたはこれらから始めたいと思うかもしれません。リクエストでリファラー URL を送信し、複数の接続ではなく、単一の接続のみを作成できます。

この質問も参照できます

于 2012-05-14T10:07:56.430 に答える