Ich hatte schon immer die Angewohnheit, amerikanische Fernsehserien zu schauen, um einerseits mein Englischhören zu üben und andererseits um mir die Zeit zu vertreiben. Früher war es möglich, online auf Video-Websites zu schauen, aber seit der Beschränkungsanordnung der staatlichen Verwaltung für Radio, Film und Fernsehen scheint es, dass importierte amerikanische und britische Dramen nicht mehr wie zuvor gleichzeitig aktualisiert werden. Wie kann ich als Nerd jedoch bereit sein, keine Dramen zu verfolgen, also habe ich online nachgesehen und eine Website zum Herunterladen von amerikanischen Dramen [Tiantian American Dramas] gefunden, die ich mit Thunder herunterladen kann. Ich bin besessen von der hochauflösenden Dokumentation der BBC, die Natur ist so schön.
Obwohl ich eine Ressourcen-Website gefunden habe, die heruntergeladen werden kann, muss ich jedes Mal den Browser öffnen, die URL eingeben, das amerikanische Drama finden und Klicken Sie dann auf den Link zum Herunterladen. Nach längerer Zeit wird der Vorgang sehr umständlich und manchmal kann der Website-Link nicht geöffnet werden, was etwas mühsam ist. Ich habe zufällig Python-Crawler gelernt, also habe ich heute aus einer Laune heraus einen Crawler geschrieben, um alle Links zu amerikanischen Dramen auf der Website abzurufen und sie in einem Textdokument zu speichern. Wenn Sie ein Drama möchten, öffnen Sie einfach den Link und kopieren Sie ihn nach Xunlei um es herunterzuladen.
Tatsächlich hatte ich ursprünglich geplant, eine Methode zu schreiben, die eine URL findet, Anfragen zum Öffnen und Crawlen des Download-Links verwendet und die gesamte Website ausgehend von der Startseite crawlt. Es gibt jedoch viele wiederholte Links und die URL der Website ist nicht so regelmäßig, wie ich dachte. Nachdem ich lange geschrieben habe, habe ich immer noch nicht die Art von divergentem Crawler geschrieben, die ich möchte genug, also arbeite weiter hart. . .
Später entdeckte ich, dass sich alle Links zur TV-Serie im Artikel befanden und nach der Artikel-URL eine Zahl stand, wie diese http://cn163.net/archives/24016/, also war ich es schlau und habe es erneut verwendet. Basierend auf der Crawler-Erfahrung, die ich zuvor geschrieben habe, besteht die Lösung darin, die URL automatisch zu generieren. Und jedes Drama ist einzigartig, also habe ich versucht herauszufinden, wie viele Artikel es gibt , und verwenden Sie dann die Bereichsfunktion, um direkt kontinuierlich Zahlen zu generieren, um die URL zu erstellen.
Aber viele URLs existieren nicht, daher hängen sie direkt auf. Keine Sorge, wir verwenden Anfragen, und der integrierte Statuscode wird verwendet, um den von der Anfrage zurückgegebenen Status zu bestimmen Da es sich um den zurückgegebenen Status handelt, überspringen wir alle Links mit Code 404 und crawlen die anderen Links, wodurch das URL-Problem gelöst wird.
Das Folgende ist der Implementierungscode der obigen Schritte.
def get_urls(self): try: for i in range(2015,25000): base_url='http://cn163.net/archives/' url=base_url+str(i)+'/' if requests.get(url).status_code == 404: continue else: self.save_links(url) except Exception,e: pass
Der Rest verlief reibungslos. Ich habe einen ähnlichen Crawler gefunden, der zuvor von jemandem im Internet geschrieben wurde, aber er hat nur einen Artikel gecrawlt, also habe ich gelernt etwas über seine regulären Ausdrücke. Ich habe BeautifulSoup verwendet, aber die Wirkung war nicht so gut wie die normale Methode, also habe ich entschieden aufgegeben. Meinem Lernen sind keine Grenzen gesetzt. Allerdings ist der Effekt nicht so ideal. Etwa die Hälfte der Links kann nicht richtig gecrawlt werden und muss weiter optimiert werden.
# -*- coding:utf-8 -*- import requests import re import sys import threading import time reload(sys) sys.setdefaultencoding('utf-8') class Archives(object): def save_links(self,url): try: data=requests.get(url,timeout=3) content=data.text link_pat='"(ed2k://\|file\|[^"]+?\.(S\d+)(E\d+)[^"]+?1024X\d{3}[^"]+?)"' name_pat=re.compile(r'<h2>(.*?)</h2>',re.S) links = set(re.findall(link_pat,content)) name=re.findall(name_pat,content) links_dict = {} count=len(links) except Exception,e: pass for i in links: links_dict[int(i[1][1:3]) * 100 + int(i[2][1:3])] = i#把剧集按s和e提取编号 try: with open(name[0].replace('/',' ')+'.txt','w') as f: print name[0] for i in sorted(list(links_dict.keys())):#按季数+集数排序顺序写入 f.write(links_dict[i][0] + '\n') print "Get links ... ", name[0], count except Exception,e: pass def get_urls(self): try: for i in range(2015,25000): base_url='http://cn163.net/archives/' url=base_url+str(i)+'/' if requests.get(url).status_code == 404: continue else: self.save_links(url) except Exception,e: pass def main(self): thread1=threading.Thread(target=self.get_urls()) thread1.start() thread1.join() if __name__ == '__main__': start=time.time() a=Archives() a.main() end=time.time() print end-start
Die Vollversion des Codes verwendet auch Multithreading, fühlt sich aber aufgrund von Pythons GIL nutzlos an. Für viele Dramen scheint es 20.000 zu sein Ich dachte, es würde lange dauern, das Crawlen abzuschließen, aber wenn man diejenigen mit falschen URLs und nicht übereinstimmenden URLs ausschließt, betrug die gesamte Crawling-Zeit weniger als 20 Minuten. Ursprünglich wollte ich Redis zum Crawlen auf zwei Linux-Rechnern verwenden, aber nach langem Hin und Her hielt ich es für unnötig, also beließ ich es dabei und werde es später tun, wenn ich mehr Daten benötige.
Ein weiteres Problem, das mich während des Vorgangs beunruhigte, war das Speichern von Dateinamen. Ich muss mich hier beschweren, dass Dateinamen im TXT-Textformat zwar Leerzeichen, Backslashes oder Klammern usw. enthalten dürfen. Das ist das Problem. Ich habe den ganzen Morgen damit verbracht, die Daten zu durchsuchen miserabel. .
Weitere Artikel zu Python-Crawlern, die amerikanische Drama-Websites crawlen, finden Sie auf der chinesischen PHP-Website!