PythonのParsimミヌムサヌバヌブロッキングをバむパスする方法

幎末幎始は、居心地の良い家庭環境で矎しく装食され、心に倧切な2k17ミヌムを思い出し、゚レクトロニックアヌツの良心のように氞遠に残す玠晎らしい機䌚です。



しかし、サラダで十分に味付けされた良心でさえ、目が芚め、自分自身をたずめお有益な掻動に埓事するこずを少なくずも少し芁求したした。 したがっお、ビゞネスず喜びを組み合わせお、お気に入りのミヌムを䟋ずしお䜿甚しお、小さなベヌスに自分を解析する方法を怜蚎したした。
デヌタ、すべおの皮類のロック、トラップ、および途䞭でサヌバヌによっお蚭定された制限をバむパスしたす。 興味のある方はすべお猫に招埅されたす。


機械孊習、蚈量経枈孊、統蚈、および他の倚くのデヌタサむ゚ンスがパタヌンを探しおいたす。 勇敢なむンクむゞタヌアナリストは毎日、さたざたな方法で自然を拷問し、宇宙を䜜成したデヌタを生成するすばらしいプロセスがどのように機胜するかに぀いおの情報を匕き出したす。 スペむンの審問官は、日々の掻動で被害者の肉䜓を盎接䜿甚しおいたした。 しかし、自然は遍圚し、明確な物理的倖芳を持ちたせん。 このため、珟代の異端審問官の職業には奇劙な特城がありたす。自然の拷問は、どこかから取らなければならないデヌタの分析を通しお起こりたす。 通垞、平和コレクタヌはデヌタを審問官に持ち蟌みたす。 この蚘事は、デヌタがどこから来お、どのようにそれを少し収集するこずができるかに぀いおの秘密のベヌルをわずかに開くように蚭蚈されおいたす。


私たちのモットヌは、キャプテンのゞャック・スパロりの有名なフレヌズでした「すべおを手に入れ、䜕も䞎えない」。 時々、ミヌムを収集するためにかなりギャングの方法を䜿甚する必芁がありたす。 しかし、私たちは平和なデヌタ収集者のたたであり、決しおギャングになるこずはありたせん。 メむンストレヌゞからミヌムを取埗したす。



1.远Break匏


1.1。 䜕を手に入れたいですか


したがっお、 knowyourmeme.comを解析しお 、さたざたな倉数を取埗したす。



さらに、これをすべお行わずにこれを実行したい



デヌタをダりンロヌドしおゎミから消去した埌、モデルの構築を開始できたす。 たずえば、パラメヌタによっおミヌムの人気を予枬しおみおください。 しかし、これはすべお埌のものであり、ここでいく぀かの定矩に粟通したす。



1.2。 HTMLずは䜕ですか


HTMLHyperText Markup Languageは、MarkdownたたはLaTeXず同じマヌクアップ蚀語です。 さたざたなサむトを蚘述するための暙準です。 この蚀語のコマンドはタグず呌ばれたす 。 絶察に任意のサむトを開いた堎合、マりスの右ボタンをクリックし、 View page source ]をクリックするず、このサむトのHTMLスケルトンが衚瀺されたす。


HTMLペヌゞは、ネストされたタグのセットにすぎないこずがわかりたす。 たずえば、次のタグに気付くかもしれたせん。



通垞、 <...>コマンドはタグを開き、 </...>はタグを閉じたす。 これら2぀のチヌムの間にあるすべおのものは、タグが指瀺する芏則に埓いたす。 たずえば、 <p>ず</p>間にあるものはすべお独立した段萜です。


タグは、 <html>ルヌトを持぀䞀皮のツリヌを圢成し、ペヌゞをさたざたな論理郚分に分割したす。 各タグには、独自の子孫子を含めるこずができたす-埋め蟌たれおいるタグずその芪。


たずえば、HTMLペヌゞツリヌは次のようになりたす。


 <html> <head>  </head> <body> <div>       </div> <div>    <b> ,   </b> </div>    </body> </html> 


テキストず同様にこのhtmlを䜿甚するこずも、ツリヌを䜿甚するこずもできたす。 このツリヌをバむパスするず、Webペヌゞが解析されたす。 この倚様性の䞭から必芁なノヌドだけを芋぀けお、そこから情報を取埗したす


これらのツリヌを手動でトラバヌスするこずはあたり良くないので、ツリヌをトラバヌスするための特別な蚀語がありたす。



1.3。 最初のリク゚スト


Webペヌゞにアクセスするず、 requestsモゞュヌルを受信できたす。 アップロヌドしおください。 䌚瀟向けに、より効率的なパッケヌゞをいく぀かアップロヌドしたす。


 import requests #     import numpy as np #   ,    import pandas as pd #    import time #   - 

高貎な研究目的のために、察応するペヌゞから各ミヌムのデヌタを収集する必芁がありたす。 ただし、最初にこれらのペヌゞのアドレスを取埗する必芁がありたす。 したがっお、すべおのミヌムがレむア​​りトされたメむンペヌゞを開きたす。 次のようになりたす。



ここから、リストされた各ミヌムにリンクをドラッグしたす。 メむンペヌゞのアドレスを倉数page_linkし、 requestsラむブラリを䜿甚しお開きたす。


 page_link = 'http://knowyourmeme.com/memes/all/page/1' response = requests.get(page_link) response 

 Out: <Response [403]> 

そしお、これが最初の問題です に向ける たた、サヌバヌが利甚可胜でリク゚ストを凊理できる堎合、403rd゚ラヌがサヌバヌによっお発行されたすが、個人的な理由でこれを拒吊しおいたす。


理由を調べおみたしょう。 これを行うために、サヌバヌに送信された最終リク゚ストがどのように芋えたか、より具䜓的には、サヌバヌの目にはナヌザヌ゚ヌゞェントがどのように芋えたかを確認したす。


 for key, value in response.request.headers.items(): print(key+": "+value) 

 Out: User-Agent: python-requests/2.14.2 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive 

python䞊に座っおおり、バヌゞョン2.14.2で芁求ラむブラリを䜿甚しおいるこずをサヌバヌに明らかにしたようです。 おそらく、これがサヌバヌに私たちの善意に関するいく぀かの疑念を匕き起こし、圌は容赊なく私たちを拒吊するこずにしたした。 比范のために、健康な人のリク゚ストヘッダヌがどのように芋えるかを確認できたす。



圓然のこずながら、控えめなリク゚ストは、通垞のブラりザからのリク゚スト䞭に送信されるこのような豊富なメタ情報ず競合したせん。 幞いなこずに、だれも私たちが人間のふりをしお、停のナヌザヌ゚ヌゞェントの生成を䜿甚しおサヌバヌの目にちりを投げるこずを気にしたせん。 このタスクに察凊するラむブラリはたくさんありたすが、個人的にはfake-useragent䞀番奜きです。 さたざたな郚分からメ゜ッドを呌び出すず、オペレヌティングシステム、仕様、ブラりザバヌゞョンのランダムな組み合わせが生成され、リク゚ストに枡すこずができたす。


 #       from fake_useragent import UserAgent UserAgent().chrome 

 Out: 'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2224.3 Safari/537.36' 

生成された゚ヌゞェントを䜿甚しお、リク゚ストを再床実行しおみたしょう


 response = requests.get(page_link, headers={'User-Agent': UserAgent().chrome}) response 

 Out: <Response [200]> 

玠晎らしい、私たちの小さな倉装 それは機胜し、ceivされたサヌバヌは祝犏された200応答を忠実に発行したした-接続が確立され、デヌタが受信され、すべおが玠晎らしいです 結局のずころ、䜕を埗たのか芋おみたしょう。


 html = response.content html[:1000] 

 Out: b'<!DOCTYPE html>\n<html xmlns:fb=\'http://www.facebook.com/2008/fbml\' xmlns=\'http://www.w3.org/1999/xhtml\'>\n<head>\n<meta content=\'text/html; charset=utf-8\' http-equiv=\'Content-Type\'>\n<script type="text/javascript">window.NREUM||(NREUM={});NREUM.info={"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"c1a6d52f38","applicationID":"31165848","transactionName":"dFdfRUpeWglTQB8GDUNKWFRLHlcJWg==","queueTime":0,"applicationTime":59,"agent":""}</script>\n<script type="text/javascript">window.NREUM||(NREUM={}),__nr_require=function(e,t,n){function r(n){if(!t[n]){var o=t[n]={exports:{}};e[n][0].call(o.exports,function(t){var o=e[n][1][t];return r(o||t)},o,o.exports)}return t[n].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<n.length;o++)r(n[o]);return r}({1:[function(e,t,n){function r(){}function o(e,t,n){return function(){return i(e,[f.now()].concat(u(arguments)),t?null:this,n),t?void 0:this}}var i=e("handle"),a=e(2),u=e(3),c=e("ee").get("tracer")' 

消化できないように芋えたすが、このケヌスからもっずきれいなものを溶接するのはどうですか たずえば、玠晎らしいスヌプ。


1.4。 玠晎らしいスヌプ



bs4パッケヌゞ、別名BeautifulSoup その人の芪友-ドキュメントぞのハむパヌリンクがありたすは、䞍思議の囜のアリスの矎しいスヌプに関する詩にちなんで呜名されたした。


Wonderful Soupは、ペヌゞの生の未凊理のHTMLコヌドから、Webペヌゞの必芁なタグ、クラス、属性、テキスト、およびその他の芁玠を怜玢するのに非垞に䟿利な構造化されたデヌタ配列を提䟛する完党に魔法のラむブラリです。


BeautifulSoupず呌ばれるパッケヌゞは、おそらく私たちが必芁ずするものではありたせん。 これは3番目のバヌゞョン Beautiful Soup 3 であり、4番目を䜿甚したす。 beautifulsoup4パッケヌゞをむンストヌルする必芁がありたす。 完党に楜しいものにするためには、むンポヌトする際に別のパッケヌゞ名bs4を指定し、 BeautifulSoupずいう関数をむンポヌトする必芁がありたす。 䞀般に、最初は混乱しやすいですが、これらの困難を克服する必芁がありたす。

このパッケヌゞは、ペヌゞの生のXMLコヌドでも機胜したすXMLはワヌプされ、コマンドであるHTMLを䜿甚しお方蚀に倉換されたす。 パッケヌゞがXMLマヌクアップで正しく機胜するためには、歊噚庫党䜓に加えおxmlパッケヌゞをむンストヌルする必芁がありたす。


 from bs4 import BeautifulSoup 

BeautifulSoup関数に、最近受け取ったWebペヌゞのテキストを枡したす。


 soup = BeautifulSoup(html,'html.parser') #      lxml, #      

次のようなものが埗られたす。


 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/> <script type="text/javascript">window.NREUM||(NREUM={});NREUM.info={"beacon":"bam.nr-data.net","errorBeacon":"bam.nr-data.net","licenseKey":"c1a6d52f38","applicationID":"31165848","transactionName":"dFdfRUpeWglTQB8GDUNKWFRLHkUNWUU=","queueTime":0,"applicationTime":24,"agent":""}</script> <script type="text/javascript">window.NREUM||(NREUM={}),__nr_require=function(e,n,t){function r(t){if(!n[t]){var o=n[t]={exports:{}};e[t][0].call(o.exports,function(n){var o=e[t][1][n];return r(o||n)},o,o.exports)}return n[t].exports}if("function"==typeof __nr_require)return __nr_require;for(var o=0;o<t.length;o++)r(t[o]);return r}({1:[function(e,n,t){function r(){}function o(e,n,t){return function(){return i(e,[c.now()].concat(u(arguments)),n?null:this,t),n?void 0:this}}var i=e("handle"),a=e(2),u=e(3),f=e("ee").get("tracer"),c=e("loader"),s=NREUM;"undefined"==typeof window.newrelic&&(newrelic=s);var p= 

ずっず良くなりたしたよね soup倉数には䜕がありたすか 䞍泚意なナヌザヌは、ほずんど䜕も倉わっおいないず蚀うでしょう。 しかし、これはそうではありたせん。 これで、ペヌゞのHTMLツリヌを自由にロヌミングし、子䟛、芪を探しおそれらを取り出すこずができたす


たずえば、タグからのパスを指定しお、ピヌクを移動できたす。


 soup.html.head.title 

 Out: <title>All Entries | Know Your Meme</title> 

textメ゜ッドを䜿甚しお、さたよう堎所からテキストを取埗できtext 。


 soup.html.head.title.text 

 Out: 'All Entries | Know Your Meme' 

さらに、芁玠のアドレスがわかれば、すぐに芋぀けるこずができたす。 たずえば、クラスでこれを行うこずができたす。 次のコマンドは、タグ内にあり、クラスのphotoを持぀芁玠を芋぀けるこずです。


 obj = soup.find('a', attrs = {'class':'photo'}) obj 

 Out: <a class="photo left" href="/memes/nu-male-smile" target="_self"><img alt='The "Nu-Male Smile" Is Duck Face for Men' data-src="http://i0.kym-cdn.com/featured_items/icons/wide/000/007/585/7a2.jpg" height="112" src="http://a.kym-cdn.com/assets/blank-b3f96f160b75b1b49b426754ba188fe8.gif" title='The "Nu-Male Smile" Is Duck Face for Men' width="198"/> <div class="info abs"> <div class="c"> The "Nu-Male Smile" Is Duck Face for Men </div> </div> </a> 

しかし、私たちの予想に反しお、匕き出されたオブゞェクトには"photo left"クラスがありたす。 BeautifulSoup4はclass属性を個別の倀のセットず芋なすため、ラむブラリの"photo left"は["photo", "left"]に盞圓し["photo", "left"]指定したこのクラス"photo"倀はこのリストに含たれたす。 このような䞍快な状況を避け、䞍芁なリンクをクリックするには、独自の機胜を䜿甚しお完党䞀臎を蚭定する必芁がありたす。


 obj = soup.find(lambda tag: tag.name == 'a' and tag.get('class') == ['photo']) obj 

 Out: <a class="photo" href="/memes/people/mf-doom"><img alt="MF DOOM" data-src="http://i0.kym-cdn.com/entries/icons/medium/000/025/149/1489698959244.jpg" src="http://a.kym-cdn.com/assets/blank-b3f96f160b75b1b49b426754ba188fe8.gif" title="MF DOOM"/> <div class="entry-labels"> <span class="label label-submission"> Submission </span> <span class="label" style="background: #d32f2e; color: white;">Person</span> </div> </a> 

怜玢埌に取埗されたオブゞェクトもbs4構造を持っおいたす。 したがっお、すでに必芁なオブゞェクトを匕き続き怜玢できたす このミヌムぞのリンクを取埗したす。 これは、リンクが含たれおいるhref属性によっお実行できたす。


 obj.attrs['href'] 

 Out: '/memes/people/mf-doom' 

これらすべおのクレむゞヌな倉換の埌、デヌタ型が倉曎されおいるこずに泚意しおください。 今、圌らはstrです。 これは、テキストのようにそれらを操䜜し、正芏衚珟を䜿甚しお䞍芁な情報を陀倖できるこずを意味したす。


 print("    :", type(obj)) print("    :", type(obj.attrs['href'])) 

 Out:     : <class 'bs4.element.Tag'>     : <class 'str'> 

ペヌゞ䞊の耇数の芁玠に指定されたアドレスがある堎合、 findメ゜ッドは最初の芁玠のみを返したす。 このアドレスを持぀すべおの芁玠を怜玢するには、 findAllメ゜ッドを䜿甚する必芁がありたす。リストがfindAllたす。 したがっお、ミヌムのあるペヌゞぞのリンクを含むすべおのオブゞェクトを䞀床の怜玢で取埗できたす。


 meme_links = soup.findAll(lambda tag: tag.name == 'a' and tag.get('class') == ['photo']) meme_links[:3] 

 Out: [<a class="photo" href="/memes/people/mf-doom"><img alt="MF DOOM" data-src="http://i0.kym-cdn.com/entries/icons/medium/000/025/149/1489698959244.jpg" src="http://a.kym-cdn.com/assets/blank-b3f96f160b75b1b49b426754ba188fe8.gif" title="MF DOOM"/> <div class="entry-labels"> <span class="label label-submission"> Submission </span> <span class="label" style="background: #d32f2e; color: white;">Person</span> </div> </a>, <a class="photo" href="/memes/here-lies-beavis-he-never-scored"><img alt="Here Lies Beavis. He Never Scored." data-src="http://i0.kym-cdn.com/entries/icons/medium/000/025/148/maxresdefault.jpg" src="http://a.kym-cdn.com/assets/blank-b3f96f160b75b1b49b426754ba188fe8.gif" title="Here Lies Beavis. He Never Scored."/> <div class="entry-labels"> <span class="label label-submission"> Submission </span> </div> </a>, <a class="photo" href="/memes/people/vanossgaming"><img alt="VanossGaming" data-src="http://i0.kym-cdn.com/entries/icons/medium/000/025/147/Evan-Fong-e1501621844732.jpg" src="http://a.kym-cdn.com/assets/blank-b3f96f160b75b1b49b426754ba188fe8.gif" title="VanossGaming"/> <div class="entry-labels"> <span class="label label-submission"> Submission </span> <span class="label" style="background: #d32f2e; color: white;">Person</span> </div> </a>] 

ゎミからリストをクリアするこずは残っおいたす


 meme_links = [link.attrs['href'] for link in meme_links] meme_links[:10] 

 Out: ['/memes/people/mf-doom', '/memes/here-lies-beavis-he-never-scored', '/memes/people/vanossgaming', '/memes/stream-sniping', '/memes/kids-describe-god-to-an-illustrator', '/memes/bad-teacher', '/memes/people/adam-the-creator', '/memes/but-can-you-do-this', '/memes/people/ken-ashcorp', '/memes/heartbroken-cowboy'] 

完了したした。1぀の怜玢ペヌゞで、ミヌムの数で正確に16個のリンクを取埗したした。


もちろん、その䜏所でアむテムを怜玢できるずいうのは玠晎らしいこずですが、この䜏所はどこで入手できたすか セレクタヌガゞェットなど、ペヌゞから必芁なタグをプルできるブラりザヌに䜕らかの皮類のナヌティリティをむンストヌルできたす。


ただし、このパスは真のサムラむには適しおいたせん。 Bushidoのフォロワヌには、別の方法がありたす。必芁な各芁玠のタグを手動で怜玢したす。 これを行うには、ブラりザりィンドりを右クリックしお、[ 怜査 ]ボタンを抌す必芁がありたす。 これらすべおの操䜜の埌、ブラりザは次のようになりたす。



遞択したオブゞェクトのアドレスを含むポップアップHTMLピヌスは、コヌドに簡単にコピヌしお、残虐行為を楜しむこずができたす。


最埌の瞬間が残っおいたす。 珟圚のペヌゞからすべおのミヌムをダりンロヌドしたら、どういうわけか次のペヌゞに移動する必芁がありたす。 サむトでは、ミヌムを䜿甚しおペヌゞを䞋にスクロヌルするだけでこれを行うこずができたす。javascript関数は新しいミヌムを珟圚のりィンドりに衚瀺したすが、これらの機胜には觊れないようにしたす。


通垞、怜玢甚にサむトに蚭定したすべおのパラメヌタヌは、hrefの構造に衚瀺されたす。 ミヌムも䟋倖ではありたせん。 ミヌムの最初の郚分を取埗する堎合は、リンクでサむトを参照する必芁がありたす


http://knowyourmeme.com/memes/all/page/1

16個のミヌムで2番目の䜍眮を取埗する堎合、リンクをわずかに倉曎する必芁がありたす。぀たり、ペヌゞ番号を2に眮き換えたす。


http://knowyourmeme.com/memes/all/page/2

このような簡単な方法で、すべおのペヌゞを閲芧しおメモリアルを奪うこずができたす。 最埌に、䞊蚘のすべおの操䜜を含む矎しい関数をラップしたす。


ミヌムぞのリンクをダりンロヌドする機胜
 def getPageLinks(page_number): """     ,     page_number: int/string     """ #      page_link = 'http://knowyourmeme.com/memes/all/page/{}'.format(page_number) #     response = requests.get(page_link, headers={'User-Agent': UserAgent().chrome}) if not response.ok: #    ,       return [] #        html = response.content soup = BeautifulSoup(html,'html.parser') # ,           meme_links = soup.findAll(lambda tag: tag.name == 'a' and tag.get('class') == ['photo']) meme_links = ['http://knowyourmeme.com' + link.attrs['href'] for link in meme_links] return meme_links 

機胜をテストし、すべおが正垞であるこずを確認したす


 meme_links = getPageLinks(1) meme_links[:2] 

 Out: ['http://knowyourmeme.com/memes/people/mf-doom', 'http://knowyourmeme.com/memes/here-lies-beavis-he-never-scored'] 

さお、この関数は機胜し、理論的には17171のすべおのミヌムぞのリンクを取埗できたす。そのためには17171/16〜1074ペヌゞを通過する必芁がありたす。 非垞に倚くのリク゚ストでサヌバヌを混乱させる前に、特定のミヌムに関するすべおの必芁な情報を取埗する方法を芋おみたしょう。


1.5匷盗の最終準備


リンクずの類掚により、䜕でも匕き出す​​こずができたす。 これを行うには、いく぀かの手順を実行する必芁がありたす。


  1. ミヌムでペヌゞを開く
  2. 必芁な情報のタグを探したす
  3. すべおを矎しいスヌプに入れたす
  4. ......
  5. 利益

奜奇心reader盛な読者の頭の䞭で情報を統合するには、ミヌムのビュヌの数を匕き出したす。


そしお、䟋ずしお、このサむトで最も人気のあるミヌム、Dogeを取り䞊げたしょう。Dogeは、2018幎1月1日時点で1,200䞇回を超えおいたす。


私たちの研究の心にずっお倧切な情報を埗るペヌゞ自䜓は、次のようになりたす。



前ず同じように、最初に、ペヌゞぞのリンクを倉数に保存し、そのコンテンツを匕き出したす。


 meme_page = 'http://knowyourmeme.com/memes/doge' response = requests.get(meme_page, headers={'User-Agent': UserAgent().chrome}) html = response.content soup = BeautifulSoup(html,'html.parser') 

ミヌムに関連するダりンロヌドされたビデオや写真の数だけでなく、ビュヌ、コメントの統蚈を取埗する方法を芋おみたしょう。 これらはすべお、右䞊のタグ"dd"䞋に、クラス"views" 、 "videos" 、 "photos" 、および"comments"ずずもに保存され"comments"


 views = soup.find('dd', attrs={'class':'views'}) print(views) 

 Out: <dd class="views" title="12,318,185 Views"> <a href="/memes/doge" rel="nofollow">12,318,185</a> </dd> 

タグず句読点をクリアする


 views = views.find('a').text views = int(views.replace(',', '')) print(views) 

 Out: 12318185 

繰り返したすが、すべおを小さな関数に詰め蟌みたす。


ミヌムごずに統蚈を返す関数
 def getStats(soup, stats): """    //... soup:  bs4.BeautifulSoup    stats: string views/videos/photos/comments """ obj = soup.find('dd', attrs={'class':stats}) obj = obj.find('a').text obj = int(obj.replace(',', '')) return obj 

すべお準備完了です


 views = getStats(soup, stats='views') videos = getStats(soup, stats='videos') photos = getStats(soup, stats='photos') comments = getStats(soup, stats='comments') print(": {}\n: {}\n: {}\n: {}".format(views, videos, photos, comments)) 

 Out: : 12318185 : 59 : 1645 : 918 

別の興味深い研究-ミヌムを远加した日付ず時刻を取埗したす。 ブラりザでペヌゞを芋るず、匕き出すこずができる最倧の情報は、発行からAdded 4 years ago by NovaXPれおから経過した幎数であるず考えるでしょう。 ただし、あきらめるこずはあたりありたせん。htmlの根底に登り、この碑文の原因ずなっおいる郚分を掘り䞋げたす。



うん 远加日に関する詳现は、分単䜍で正確です。 小孊生



 date = soup.find('abbr', attrs={'class':'timeago'}).attrs['title'] date 

 Out: '2017-12-31T01:59:14-05:00' 

実際、パヌサヌは予枬䞍胜です。 倚くの堎合、解析するペヌゞは非垞に異皮の構造を持っおいたす。 たずえば、ミヌムを解析しおいる堎合、説明はペヌゞの䞀郚に衚瀺される堎合がありたすが、䞀郚には衚瀺されない堎合がありたす。 コヌドが最初に説明の欠劂に遭遇するずすぐに、゚ラヌをスロヌしお停止したす。 すべおのデヌタを適切に収集するには、䟋倖を登録する必芁がありたす。 ミヌムストアには蚭備が敎っおおり、緊急事態は発生しないはずです。
それにもかかわらず、私は本圓に朝起きお、コヌドが20回繰り返され、゚ラヌにぶ぀かり、切り萜ずされたのを芋たくありたせん。 これを防ぐには、たずえば、 try - exceptコンストラクトを䜿甚し、 try - except゚ラヌを単玔に凊理したす。 むンタヌネットで䟋倖に぀いお読むこずができたす。 この堎合、間違いを犯すこずはできたせんが、ペヌゞに必芁な芁玠があるかどうかを事前にチェックし、通垞のif - elseを䜿甚せずに、解析を詊みたす。


たずえば、ミヌムのステヌタスを匕き出したいので、これを取り巻くタグを芋぀けたす。


 properties = soup.find('aside', attrs={'class':'left'}) meme_status = properties.find("dd") meme_status 

 Out: <dd> Confirmed </dd> 

次に、タグからテキストを抜出し、䜙分なスペヌスをすべお切り取る必芁がありたす。


 meme_status.text.strip() 

 Out: 'Confirmed' 

ただし、ミヌムにステヌタスがないこずが突然刀明した堎合、 findメ゜ッドはvoidを返したす。 䞀方、 textメ゜ッドはタグ内のテキストを芋぀けるこずができず、゚ラヌをスロヌしたす。 このようなボむドから身を守るために、䟋倖を登録するかif - else登録できif - else 。 珟圚のミヌムはただステヌタスを持っおいるため、意図的に空のオブゞェクトずしお蚭定し、䞡方のケヌスで゚ラヌがキャッチされるこずを確認したす


 #  !   ,     meme_status = None #  !   ... # ...   try: print(meme_status.text.strip()) #   ,   ,  . except: print("Exception") # ...      if meme_status: print(meme_status.text.strip()) else: print("Empty") 

 Out: Exception Empty 

このコヌドにより、゚ラヌから身を守るこずができたす。 この堎合、 if - elseを1぀の䟿利な文字列ずしお䜿甚しお、構造党䜓を曞き換えるこずができたす。 この行は、 meme_statusかどうかを確認し、 meme_statusない堎合は無効になりたす。


 #     properties = soup.find('aside', attrs={'class':'left'}) meme_status = properties.find("dd") meme_status = "" if not meme_status else meme_status.text.strip() print(meme_status) 

 Out: Confirmed 

類掚により、ペヌゞから残りの情報を匕き出すこずができたす。そのために、再び関数を曞きたす。


ミヌムプロパティを解析するための関数
 def getProperties(soup): """   (tuple)  , , ,       soup:  bs4.BeautifulSoup    """ #  -      h1,   meme_name = soup.find('section', attrs={'class':'info'}).find('h1').text.strip() #       properties = soup.find('aside', attrs={'class':'left'}) #    -     meme_status = properties.find("dd") # oneliner,  try-except:     properties,   NoneType, #    text ,          meme_status = "" if not meme_status else meme_status.text.strip() #   -    meme_type = properties.find('a', attrs={'class':'entry-type-link'}) meme_type = "" if not meme_type else meme_type.text #        Year, #  ,       -   meme_origin_year = properties.find(text='\nYear\n') meme_origin_year = "" if not meme_origin_year else meme_origin_year.parent.find_next() meme_origin_year = meme_origin_year.text.strip() #   meme_origin_place = properties.find('dd', attrs={'class':'entry_origin_link'}) meme_origin_place = "" if not meme_origin_place else meme_origin_place.text.strip() # ,    meme_tags = properties.find('dl', attrs={'id':'entry_tags'}).find('dd') meme_tags = "" if not meme_tags else meme_tags.text.strip() return meme_name, meme_status, meme_type, meme_origin_year, meme_origin_place, meme_tags 

 getProperties(soup) 

 Out: ('Doge', 'Confirmed', 'Animal', '2013', 'Tumblr', 'animal, dog, shiba inu, shibe, such doge, super shibe, japanese, super, tumblr, much, very, many, comic sans, photoshop meme, such, shiba, shibe doge, doges, dogges, reddit, comic sans ms, tumblr meme, hacked, bitcoin, dogecoin, shitposting, stare, canine') 

ミヌムプロパティがコンパむルされたす。 今、そのテキストの説明を類掚しお収集したす。


ミヌムのテキスト蚘述を解析するための関数
 def getText(soup): """     soup:  bs4.BeautifulSoup    """ #      body = soup.find('section', attrs={'class':'bodycopy'}) #  about (  ),   ,      meme_about = body.find('p') meme_about = "" if not meme_about else meme_about.text #  origin     Origin  History, #  ,       -   meme_origin = body.find(text='Origin') or body.find(text='History') meme_origin = "" if not meme_origin else meme_origin.parent.find_next().text #    (  )       if body.text: other_text = body.text.strip().split('\n')[4:] other_text = " ".join(other_text).strip() else: other_text = "" return meme_about, meme_origin, other_text 

 meme_about, meme_origin, other_text = getText(soup) print("  :\n{}\n\n:\n{}\n\n :\n{}...\n"\ .format(meme_about, meme_origin, other_text[:200])) 

 Out:   : Doge is a slang term for “dog” that is primarily associated with pictures of Shiba Inus (nicknamed “Shibe”) and internal monologue captions on Tumblr. These photos may be photoshopped to change the dog's face or captioned with interior monologues in Comic Sans font. : The use of the misspelled word “doge” to refer to a dog dates back to June 24th, 2005, when it was mentioned in an episode of Homestar Runner's puppet show. In the episode titled “Biz Cas Fri 1”[2], Homestar calls Strong Bad his “doge” while trying to distract him from his work.  : Identity On February 23rd, 2010, Japanese kindergarten teacher Atsuko Sato posted several photos of her rescue-adopted Shiba Inu dog Kabosu to her personal blog.[38] Among the photos included a peculi... 

, ,


,
 def getMemeData(meme_page): """    ,      meme_page: string      """ #     response = requests.get(meme_page, headers={'User-Agent': UserAgent().chrome}) if not response.ok: #    ,    return response.status_code #        html = response.content soup = BeautifulSoup(html,'html.parser') #       views = getStats(soup=soup, stats='views') videos = getStats(soup=soup, stats='videos') photos = getStats(soup=soup, stats='photos') comments = getStats(soup=soup, stats='comments') #  date = soup.find('abbr', attrs={'class':'timeago'}).attrs['title'] # , ,  .. meme_name, meme_status, meme_type, meme_origin_year, meme_origin_place, meme_tags =\ getProperties(soup=soup) #   meme_about, meme_origin, other_text = getText(soup=soup) #  ,          data_row = {"name":meme_name, "status":meme_status, "type":meme_type, "origin_year":meme_origin_year, "origin_place":meme_origin_place, "date_added":date, "views":views, "videos":videos, "photos":photos, "comments":comments, "tags":meme_tags, "about":meme_about, "origin":meme_origin, "other_text":other_text} return data_row 

, ,


 final_df = pd.DataFrame(columns=['name', 'status', 'type', 'origin_year', 'origin_place', 'date_added', 'views', 'videos', 'photos', 'comments', 'tags', 'about', 'origin', 'other_text']) data_row = getMemeData('http://knowyourmeme.com/memes/doge') final_df = final_df.append(data_row, ignore_index=True) final_df 

 Out: 

お名前状態typeorigin_year...
DogeConfirmedAnimal2013...

. — , meme_links .


 for meme_link in meme_links: data_row = getMemeData(meme_link) final_df = final_df.append(data_row, ignore_index=True) 

 Out: 

お名前状態typeorigin_year...
DogeConfirmedAnimal2013...
Charles C. JohnsonSubmissionActivist2013...
Bat- (Prefix)SubmissionSnowclone2018...
The Eric Andre ShowDeadpoolTV Show2012...
HopsinSubmissionMusician2003...

いいね , , , — , , .


2.


2.1


圌がいる , , , , — . , . 1075. try-except . .


 #   .       #   tqdm_notebook    from tqdm import tqdm_notebook final_df = pd.DataFrame(columns=['name', 'status', 'type', 'origin_year', 'origin_place', 'date_added', 'views', 'videos', 'photos', 'comments', 'tags', 'about', 'origin', 'other_text']) for page_number in tqdm_notebook(range(1075), desc='Pages'): #      meme_links = getPageLinks(page_number) for meme_link in tqdm_notebook(meme_links, desc='Memes', leave=False): #        for i in range(5): try: #       data_row = getMemeData(meme_link) #      final_df = final_df.append(data_row, ignore_index=True) #    -     break except: # ,    ,     print('AHTUNG! parsing once again:', meme_link) continue 

! - - , , .



, , , . .



2.2 —


, . , .


. , , , request-header . , IP, , IP . , -, IP , "". : — - , — ?


Tor . , Tor , . , , , , , . , Tor, , . :



, , , Tor . ip-. get- , IP


 def checkIP(): ip = requests.get('http://checkip.dyndns.org').content soup = BeautifulSoup(ip, 'html.parser') print(soup.find('body').text) checkIP() 

 Out: Current IP Address: 82.198.191.130 

ip Tor . — , — .


tor , . tor .



2.3


. ip PySocks . , , pip3 install PySocks .


9150. socks socket . , – - .


 import socks import socket socks.set_default_proxy(socks.SOCKS5, "localhost", 9150) socket.socket = socks.socksocket 

ip-a.


 checkIP() 

 Out: Current IP Address: 51.15.92.24 

, .



 !



ip-.


 data_row = getMemeData('http://knowyourmeme.com/memes/doge') for key, value in data_row.items(): print(key.capitalize()+":", str(value)[:200], end='\n\n') 

 Out: Name: Doge Status: Confirmed Type: Animal Origin_year: 2013 Origin_place: Tumblr Date_added: 2017-12-31T01:59:14-05:00 Views: 12318185 Videos: 59 Photos: 1645 Comments: 918 Tags: animal, dog, shiba inu, shibe, such doge, super shibe, japanese, super, tumblr, much, very, many, comic sans, photoshop meme, such, shiba, shibe doge, doges, dogges, reddit, comic sans ms, tumblr meme About: Doge is a slang term for “dog” that is primarily associated with pictures of Shiba Inus (nicknamed “Shibe”) and internal monologue captions on Tumblr... 

. . . .


, : , - ip 10 . , ? , , Tor torrc ( ~/Library/Application Support/TorBrowser-Data/torrc , — ) . :


 CircuitBuildTimeout 10 LearnCircuitBuildTimeout 0 MaxCircuitDirtiness 10 

ip 10 . .


 for i in range(10): checkIP() time.sleep(5) 

 Out: Current IP Address: 89.31.57.5 Current IP Address: 93.174.93.71 Current IP Address: 62.210.207.52 Current IP Address: 209.141.43.42 Current IP Address: 209.141.43.42 Current IP Address: 162.247.72.216 Current IP Address: 185.220.101.17 Current IP Address: 193.171.202.150 Current IP Address: 128.31.0.13 Current IP Address: 185.163.1.11 

, ip 10 . . 20 .


  1. ;
  2. ;
  3. .....
  4. 利益

 final_df = pd.DataFrame(columns=['name', 'status', 'type', 'origin_year', 'origin_place', 'date_added', 'views', 'videos', 'photos', 'comments', 'tags', 'about', 'origin', 'other_text']) for page_number in tqdm_notebook(range(1075), desc='Pages'): #      meme_links = getPageLinks(page_number) for meme_link in tqdm_notebook(meme_links, desc='Memes', leave=False): #        for i in range(5): try: #       data_row = getMemeData(meme_link) #      final_df = final_df.append(data_row, ignore_index=True) #    -     break except: # ,    ,     continue final_df.to_csv('MEMES.csv') 

. . . : , ip ?


2.4


ip . Github - TorCrawler.py . , , . . . , .


, torrc . /usr/local/etc/tor/ , /etc/tor/ . .


  1. tor --hash-password mypassword
  2. torrc vim , nano atom
  3. torrc- , HashedControlPassword
  4. , HashedControlPassword
  5. ( ) ControlPort 9051
  6. .

tor . : service tor start , : tor .


.


 from TorCrawler import TorCrawler #   ,     crawler = TorCrawler(ctrl_pass='mypassword') 

get- , bs4.


 meme_page = 'http://knowyourmeme.com/memes/doge' response = crawler.get(meme_page, headers={'User-Agent': UserAgent().chrome}) type(response) 

 Out: bs4.BeautifulSoup 

- .


 views = response.find('dd', attrs={'class':'views'}) views 

 Out: <dd class="views" title="12,318,185 Views"> <a href="/memes/doge" rel="nofollow">12,318,185</a> </dd> 

IP


 crawler.ip 

 Out: '51.15.40.23' 

ip 25 . n_requests . , .


 crawler.n_requests 

 Out: 25 

, ip .


 crawler.rotate() 

 IP successfully rotated. New IP: 62.176.4.1 

, , IP . .


. .


おわりに


, . — , , , , - , , , . , , , , , DDoS-. , , — , — .


— - , . time.sleep() request-header — .


!


: filfonul , Skolopendriy





Source: https://habr.com/ru/post/J346632/


All Articles