2012-04-05 9 views
3

Ich schreibe einen sehr einfachen Web-Crawler und versuche, 'robots.txt' Dateien zu parsen. Ich fand das robotparser Modul in der Standardbibliothek, die genau dies tun sollte. Ich benutze Python 2.7.2. Leider lädt mein Code die 'robots.txt' Dateien nicht richtig, und ich kann nicht herausfinden, warum.Python robotparser Modul lädt 'robots.txt' nicht

Hier ist der relevante Ausschnitt aus meinem Code:

from urlparse import urlparse, urljoin 
import robotparser 

def get_all_links(page, url): 
    links = [] 
    page_url = urlparse(url) 
    base = page_url[0] + '://' + page_url[1] 
    robots_url = urljoin(base, '/robots.txt') 
    rp = robotparser.RobotFileParser() 
    rp.set_url(robots_url) 
    rp.read() 
    for link in page.find_all('a'): 
     link_url = link.get('href') 
     print "Found a link: ", link_url 
     if not rp.can_fetch('*', link_url): 
      print "Page off limits!" 
      pass 

Hier page ist ein analysiert BeautifulSoup Objekt und url ist eine URL als String gespeichert. Der Parser liest eine leere 'robots.txt'-Datei anstelle der an der angegebenen URL ein und gibt True an alle can_fetch()-Abfragen zurück. Es sieht so aus, als würde es entweder die URL nicht öffnen oder die Textdatei nicht lesen.

Ich habe es auch im interaktiven Interpreter versucht. Dies geschieht mit der gleichen Syntax wie die documentation Seite.

Python 2.7.2 (default, Aug 18 2011, 18:04:39) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import robotparser 
>>> url = 'http://www.udacity-forums.com/robots.txt' 
>>> rp = robotparser.RobotFileParser() 
>>> rp.set_url(url) 
>>> rp.read() 
>>> print rp 

>>> 

Die Linie print rp sollte den Inhalt der 'robots.txt' Datei drucken, aber es gibt leer. Noch frustrierender, theseexamples funktionieren beide tadellos wie geschrieben, aber scheitern, wenn ich meine eigene URL versuche. Ich bin ziemlich neu in Python und ich kann nicht herausfinden, was falsch läuft. Soweit ich das beurteilen kann, benutze ich das Modul genauso wie die Dokumentation und Beispiele. Danke für jede Hilfe!

UPDATE 1: Hier sind ein paar Zeilen aus dem Dolmetscher, falls print rp wäre keine gute Methode zu überprüfen, ob 'robots.txt' in gelesen Die path, host und url Attribute sind korrekt, aber die Einträge aus. 'robots.txt' noch nicht eingelesene

>>> rp 
<robotparser.RobotFileParser instance at 0x1004debd8> 
>>> dir(rp) 
['__doc__', '__init__', '__module__', '__str__', '_add_entry', 'allow_all', 'can_fetch', 'default_entry', 'disallow_all', 'entries', 'errcode', 'host', 'last_checked', 'modified', 'mtime', 'parse', 'path', 'read', 'set_url', 'url'] 
>>> rp.path 
'/robots.txt' 
>>> rp.host 
'www.udacity-forums.com' 
>>> rp.entries 
[] 
>>> rp.url 
'http://www.udacity-forums.com/robots.txt' 
>>> 

UPDATE 2:. ich dieses Problem gelöst haben this external library unter Verwendung 'robots.txt' Dateien zu analysieren. (Aber ich habe die ursprüngliche Frage nicht beantwortet!) Nachdem ich etwas mehr Zeit im Terminal verbracht habe, ist meine beste Schätzung, dass robotparser bestimmte Zusätze zu der 'robots.txt' Spezifikation nicht behandeln kann, wie Sitemap, und Probleme mit Leerzeilen hat. Es liest Dateien von z.B. Stack Overflow und Python.org, aber nicht Google, YouTube oder meine ursprüngliche Udacity-Datei, die Sitemap Anweisungen und Leerzeilen enthalten. Ich würde es trotzdem schätzen, wenn jemand, der schlauer ist als ich, dies bestätigen oder erklären könnte!

+0

Übrigens, Sie können dieses Snippet im Kontext sehen [hier] (https://github.com/ecmendenhall/DaveDaveFind/blob/master/crawler/udacity_crawler.py), falls ich etwas Relevantes weggelassen habe. – ecmendenhall

+0

Der Zeilendruck RP sollte den Inhalt der 'robots.txt' Datei drucken - bist du dir da sicher? – Hoff

+0

Ziemlich sicher. Wenn ich die externen Beispiele verwendete, die ich verlinkte, so verhielt es sich. Nur für den Fall, ich habe meine Frage mit weiteren Informationen vom Dolmetscher aktualisiert. Die URL-Attribute sehen alle richtig aus, aber 'entries' ist eine leere Liste. – ecmendenhall

Antwort

2

Ich habe dieses Problem gelöst, indem ich diese externe Bibliothek benutzt habe, um 'robots.txt' Dateien zu parsen. (Aber ich habe die ursprüngliche Frage nicht beantwortet!) Nachdem ich etwas mehr Zeit im Terminal verbracht habe, ist meine beste Vermutung, dass robotparser bestimmte Erweiterungen der 'robots.txt'-Spezifikation wie Sitemap nicht verarbeiten kann und Probleme mit Leerzeilen hat. Es liest Dateien von z.B. Stack Overflow und Python.org, aber nicht Google, YouTube oder meine ursprüngliche Udacity-Datei, die Sitemap-Anweisungen und Leerzeilen enthält. Ich würde es trotzdem schätzen, wenn jemand, der schlauer ist als ich, dies bestätigen oder erklären könnte!

0

könnte eine Lösung reppy Modul

pip install reppy 

Hier sind ein paar Beispiele verwenden;

In [1]: import reppy 

In [2]: x = reppy.fetch("http://google.com/robots.txt") 

In [3]: x.atts 
Out[3]: 
{'agents': {'*': <reppy.agent at 0x1fd9610>}, 
'sitemaps': ['http://www.gstatic.com/culturalinstitute/sitemaps/www_google_com_culturalinstitute/sitemap-index.xml', 
    'http://www.google.com/hostednews/sitemap_index.xml', 
    'http://www.google.com/sitemaps_webmasters.xml', 
    'http://www.google.com/ventures/sitemap_ventures.xml', 
    'http://www.gstatic.com/dictionary/static/sitemaps/sitemap_index.xml', 
    'http://www.gstatic.com/earth/gallery/sitemaps/sitemap.xml', 
    'http://www.gstatic.com/s2/sitemaps/profiles-sitemap.xml', 
    'http://www.gstatic.com/trends/websites/sitemaps/sitemapindex.xml']} 

In [4]: x.allowed("/catalogs/about", "My_crawler") # Should return True, since it's allowed. 
Out[4]: True 

In [5]: x.allowed("/catalogs", "My_crawler") # Should return False, since it's not allowed. 
Out[5]: False 

In [7]: x.allowed("/catalogs/p?", "My_crawler") # Should return True, since it's allowed. 
Out[7]: True 

In [8]: x.refresh() # Refresh robots.txt, perhaps a magic change? 

In [9]: x.ttl 
Out[9]: 3721.3556718826294 

Voila!