67


170

私は自分自身で書くことに夢中になっていますが、今は十分な時間がありません。 私はウィキペディアの open open crawlersリストを見ましたが、私はPythonで書かれたものを好むでしょう。 私はおそらくウィキペディアのページにあるツールのうちの1つを使用してそれをPythonでラップすることができることに気づいた。 私はそれをやろうと思うかもしれません - 誰かがそれらのツールのどれかについて何かアドバイスがあれば、私はそれらについて聞いて自由です。 私は、そのWebインターフェイスを介してHeritrixを使用しましたが、非常に面倒であることがわかりました。 私はこれからのプロジェクトでブラウザAPIを使うことは絶対にありません。

前もって感謝します。 また、これは私の最初のSOの質問です!

8 Answer


56


  • 私のお気に入りは Mechanizeです。優れた高度なブラウジング機能(超シンプルなフォーム入力および送信)。

  • Twillは、Mechanizeの上に構築された単純なスクリプト言語です。

  • BeautifulSoup urllib2も非常にうまく機能します。

  • Scrapは非常に有望なプロジェクトのように見えます。それは新しい。


44


http://scrapy.org/[Scrap]を使用してください。

それはツイストベースのWebクローラーフレームワークです。 まだ大規模な開発中ですが、それはすでに動作します。 たくさんの良い点があります。

  • HTML、XML、CSV、およびJavascriptを解析するための組み込みサポート

  • 画像(またはその他のメディア)でアイテムを削り取るためのメディアパイプライン、および画像ファイルもダウンロードする

  • ミドルウェア、拡張機能、およびパイプラインを使用して独自の機能を接続することによってScrapyを拡張するためのサポート

  • 圧縮、キャッシュ、Cookie、認証、ユーザーエージェントのなりすまし、robots.txtの処理、統計、クロールの深さの制限などを処理するための幅広いミドルウェアと拡張機能

  • インタラクティブなスクレイピングシェルコンソール、開発やデバッグに非常に便利

  • ボットを監視および制御するためのWeb管理コンソール

  • Scrapyプロセスへの低レベルアクセス用のTelnetコンソール

返されるHTMLのXPathセレクタを使用して、http://www.mininova.org/[mininova]トレントサイトに今日追加されているすべてのトレントファイルに関する情報を抽出するためのコード例:

クラスTorrent(ScrapedItem):合格

MininovaSpider(CrawlSpider):domain_name = 'mininova.org' start_urls = ['http://www.mininova.org/today'] rules = [Rule(RegexLinkExtractor(allow = ['/ tor / \ d']))、 'parse_torrent')]

def parse_torrent(self、response):x = HtmlXPathSelector(レスポンス)torrent = Torrent()

torrent.url = response.url torrent.name = xx( "// h1 / text()")。extract()torrent.description = xx( "// div [@ id = 'description']")。extract() )torrent.size = xx( "// div [@ id = 'info-left'] / p [2] / text()[2]")。extract()return [torrent]


6


Pythonで書かれたマルチスレッドのWebクローラーである HarvestManもチェックして、http://pypi.python.org/pypi/spiderを調べてください。 py / 0.5 [spider.py]モジュール。

そして ここ簡単なWebクローラーを構築するためのコードサンプルを見つけることができます。


3


私は Ruyaを使用しましたが、かなり良いと判断しました。


3


私はdrupalサイトにアクセスするのに必要なのでログインページを含めるために上記のスクリプトをハッキングしました。 きれいではありませんが、そこに誰かを助けるかもしれません。

#!/ usr / bin / python

インポートhttplib2インポートurllibインポートurllib2 from cookielibインポートCookieJarインポートsysインポートfrom HTMLParserインポートHTMLParser

クラスminiHTMLParser(HTMLParser):

seenQueue = [] instQueue = [] headers = {} opener = ""

def get_next_link(self):if self.instQueue == []:return '' else:return self.instQueue.pop(0)

def gethtmlfile(self、site、page):try:url = 'http://' site ''ページの応答= self.opener.open(url)で例外を除いてresponse.read()を返してください。err:print "ページsys.stderr.write( 'エラー:%s \ n'%str(err))が戻り値" "

返品

def loginSite(self、site_url):試してください:cj = CookieJar()self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

url = 'http://' site_url params = {'name': 'customer_admin'、 'pass': 'customer_admin123'、 'opt': 'ログイン'、 'form_build_id': 'form-3560fb42948a06b01d063de48aa216ab'、 'form_id' ':' user_login_block '} user_agent =' Mozilla / 4.0(互換性があります; MSIE 5.5; Windows NT) 'self.headers = {' User-Agent ':user_agent}

data = urllib.urlencode(params)response = self.opener.open(url、data)print "ログイン" return response.read()

例外を除いて、err:print "sys.stderr.writeへのログインエラー"( 'ERROR:%s \ n'%str(err))

1を返す

def handle_starttag(self、tag、attrs):if tag == 'a'の場合:newstr = str(attrs [0] [1])re.search( 'http'、newstr)==なしの場合:newstrを出力します。 search( 'mailto'、newstr)==なし:if re.search( '#'、newstr)==なし:if(news.true in self.viewedQueue)== False:プリント "追加"、newstr self.instQueue.append (newstr)self.viewedQueue.append(newstr)その他:印刷 "無視"、newstrその他:印刷 "無視"、newstrその他:印刷 "無視"、newstr

def main():

len(sys.argv)!= 3の場合: "使用法は./minispider.pyサイトリンクです" sys.exit(2)

mySpider = miniHTMLParser()

site = sys.argv [1] link = sys.argv [2]

url_login_link = site "/ node?destination = node" print "\ nログイン"、url_login_link x = mySpider.loginSite(url_login_link)

リンクしながら!= '':

印刷 "\ nリンクの確認"、link

#サイトからファイルを取得してretfile = mySpider.gethtmlfile(site、link)

#ファイルをHTMLパーサーmySpider.feed(retfile)に送ります。

#retfileをここで検索

#次のリンクを水平走査順に取得するlink = mySpider.get_next_link()

mySpider.close()

印刷 "\ ndone \ n"

__name__ == "__main__":main()の場合


3


私を信じてカール以外の何もない.. 。次のコードでは、Amazon EC2で300秒以内に10,000個のURLを並行してクロールできます。

注意: このような高速で同じドメインにアクセスしないでください。 .

#! / usr / bin / env python# -  *  - コーディング:iso-8859-1  -  *  - #vi:ts = 4:et#$ Id:retrievever-multi.py、v 1.29 2005/07/28 11:04: 13 mfx経験値

##使用法:python retrievever-multi.py [<#of#同時接続数>]#

import sysインポートpycurl

#pycurl.NOSIGNALを使うときはSIGPIPEを無視するべきです - 詳細はlibcurlチュートリアルを参照してください。 試してみてください。信号import SIGPIPE、SIG_IGNからの信号のインポートsignal.signal(signal.SIGPIPE、signal.SIG_IGN)ImportErrorを除く:pass

#args num_conn = 10を試してみてください:if sys.argv [1] == " - ":urls = sys.stdin.readlines()else:urls = open(sys.argv [1])。 sys.argv)> = 3:num_conn = int(sys.argv [2])を除いて:print "使用法:%s [<同時接続数>]"%sys.argv [0]はSystemExitを発生させます

#urlの中のurlのために(url、filename)タプルqueue = []でキューを作る:urlまたはurl [0] == "#"でなければ:continue filename = "doc_%03d.dat "%(len(queue)1)queue.append(((url、filename))

#args queueをチェックし、 "URLが指定されていません" num_urls = len(queue)num_conn = min(num_conn、num_urls)assert 1 <= num_conn <= 10000、 "無効な同時接続数" print "PycURL%s(0xに対してコンパイル) %x) "%(pycurl.version、pycurl.COMPILE_LIBCURL_VERSION_NUM)print" ----- "、num_urls、"を使用しているURL、 "num_conn"、 "connections -----"

#範囲(num_conn)内のiに対して、カールオブジェクトのリストm = pycurl.CurlMulti()m.handles = []を事前に割り当てます。c = pycurl.Curl()c.fp =なしc.setopt(pycurl.FOLLOWLOCATION、 1)c.setopt(pycurl.MAXREDIRS、5)c.setopt(pycurl.CONNECTTIMEOUT、30)c.setopt(pycurl.TIMEOUT、300)c.setopt(pycurl.NOSIGNAL、1)m.handles.append(c)

#メインループfreelist = m.handles [:] num_processed = 0、num_processed <num_urls:#queueおよびfreelistの間にマルチスタックに追加する:url、filename = queue.pop( 0)c = freelist.pop()c.fp = open(ファイル名、 "wb")c.setopt(pycurl.URL、url)c.setopt(pycurl.WRITEDATA、c.fp)m.add_handle(c)#いくつかの情報を保存するc.filename = filename c.url = url#1:retの間、マルチスタックの内部カールステートマシンを実行します。ret!= pycurl.E_CALL_MULTI_PERFORM:break#curlオブジェクトをチェックします。 ok_listのcの1:num_q、ok_list、err_list = m.info_read()の間にそれらをフリーリストに追加します。c.fp.close()c.fp =なしm.remove_handle(c)print "成功: "、c.filename、c.url、c.getinfo(pycurl.EFFECTIVE_URL)の空きリスト。 cの追加(c)、errno、errmsg、err_list:c.fp.close()c.fp =なしm.remove_handle(c)print "失敗:"、c.filename、c.url、errno、errmsg freelist。 append(c)num_processed = num_processed len(ok_list)len(err_list)num_q == 0の場合:break#現在、これ以上I / Oが保留されていません。 #select()を呼び出して、さらにデータが利用可能になるまでスリープさせます。 m.select(1.0)

#m.handles内のcのクリーンアップ:c.fpがNoneではない場合:c.fp.close()c.fp = None c.close()m.close()


2


もう1つの 単純なクモ BeautifulSoupとurllib2を使用します。 それほど洗練されたものではありません。hrefのすべてを読んでリストを作成し、それを調べます。


0


http://bauerdata.bauerhost.dk/python-program-eksempler/pyspider[pyspider.py]