2016-09-12 5 views
1

Ich möchte mit Python und BeautifulSoup4 mehrere Seiten einer Website durchblättern. Die Seiten unterscheiden sich nur durch eine einzige Nummer in der URL, so konnte ich tatsächlich eine Erklärung wie diese machen:Mehrere Seiten mit BeautifulSoup verschaben

Und mein Python-Skript ist this:

theurl = "beginningofurl/" + str(counter) + "/endofurl.html" 

Der Link, den ich mit diesem ist die Prüfung habe .

import urllib 
import urllib.request 
from bs4 import BeautifulSoup 


def category_crawler(): 
    ''' This function will crawl through an entire category, regardless how many pages it consists of. ''' 

    pager = 1 

    while pager < 11: 
     theurl = "http://www.worldofquotes.com/topic/Nature/"+str(pager)+"/index.html" 
     thepage = urllib.request.urlopen(theurl) 
     soup = BeautifulSoup(thepage, "html.parser") 

     for link in soup.findAll('blockquote'): 
      sanitized = link.find('p').text.strip() 
      spantext = link.find('a') 
      writer = spantext.find('span').text 
      print(sanitized) 
      print(writer) 
      print('---------------------------------------------------------') 


     pager += 1 

category_crawler() 

Die Frage ist also: Wie kann die hartcodierte Nummer in der while-Schleife in eine Lösung ändern, dass das Skript automatisch erkennen lässt, dass es die letzte Seite übergeben, und dann verlässt es automatisch?

+0

Woher bekommen Sie die Anzahl der Seiten? Kennst du es vorher? – alecxe

+0

Ich könnte natürlich nachsehen, aber da ich das Skript verwenden möchte, um viele verschiedene Kategorien auf derselben Seite zu scrappen, wo es in jeder Kategorie eine andere Seitenzahl gibt, möchte ich, dass das Skript die letzte findet Seite selbst. –

+0

Okay, was passiert, wenn der Zähler auf eine nicht existierende Seite zeigt? Würde die Seite mit 404 antworten? – alecxe

Antwort

0

Die Idee ist, eine Endlosschleife haben und sie brechen, wenn Sie die nicht auf der Seite „Pfeil nach rechts“ Element haben was bedeuten würde, Sie auf der letzten Seite sind, einfach und ganz logisch:

import requests 
from bs4 import BeautifulSoup 


page = 1 
url = "http://www.worldofquotes.com/topic/Nature/{page}/index.html" 
with requests.Session() as session: 
    while True: 
     response = session.get(url.format(page=page)) 
     soup = BeautifulSoup(response.content, "html.parser") 

     # TODO: parse the page and collect the results 

     if soup.find(class_="icon-arrow-right") is None: 
      break # last page 

     page += 1 
+0

Wow, danke @alecxe. Das ist viel schneller als meine Version. Sehr geschätzt. –

0

Versuchen Sie mit requests (Vermeidung von Umleitungen) und prüfen Sie, ob Sie neue Angebote erhalten.

import requests 
from bs4 import BeautifulSoup 


def category_crawler(): 
    ''' This function will crawl through an entire category, regardless how many pages it consists of. ''' 

    pager = 1 

    while pager < 11: 
     theurl = "http://www.worldofquotes.com/topic/Art/"+str(pager)+"/index.html" 
     thepage = requests.get(theurl, allow_redirects=False).text 
     soup = BeautifulSoup(thepage, "html.parser") 

     for link in soup.find_all('blockquote'): 
      sanitized = link.find('p').text.strip() 
      spantext = link.find('a') 
      writer = spantext.find('span').text 
      if not sanitized: 
       break 
      print(sanitized) 
      print(writer) 
      print('---------------------------------------------------------') 


     pager += 1 

category_crawler() 
+0

Danke Nuno, aber Sie missverstehen. Ich bekomme neue Zitate bis zum Ende, das Skript hört einfach nicht am Ende auf ... –

+0

Hast du dieses Skript ausprobiert? Das Problem ist, dass das Web von der 5. - 11. Seite (sie existiert nicht) auf die 1. umgeleitet wird, und deshalb erhalten Sie neue Zitate. Wenn Sie diese Umleitung vermeiden, erhalten Sie keine neuen Anführungszeichen und das Skript wird beendet. –

0

Hier ist mein Versuch.

Kleinere Ausgabe: Setzen Sie einen try-except Block in den Code für den Fall, dass die Umleitung Sie irgendwo hinführt, die nicht existiert.

Nun, das Hauptproblem: Wie zu vermeiden Parsing Zeug Sie schon geparst. Notieren Sie URLs, die Sie analysiert haben. Dann erkennen, ob die aktuelle URL von der Seite urllib liest (mit der geturl() Methode von thepage) wurde bereits gelesen. Arbeitete auf meinem Mac OSX-Rechner.

Hinweis: Es gibt 10 Seiten insgesamt, was ich von der Website sehe und diese Methode erfordert keine Vorkenntnisse über die HTML-Seite der Seite - es funktioniert im Allgemeinen.

import urllib 
import urllib.request 
from bs4 import BeautifulSoup 


def category_crawler(): 
    ''' This function will crawl through an entire category, regardless how many pages it consists of. ''' 
    urlarchive = []; 
    pager = 1 
    while True: 
     theurl = "http://www.worldofquotes.com/topic/Nature/"+str(pager)+"/index.html" 
     thepage = None; 
     try: 
      thepage = urllib.request.urlopen(theurl) 
      if thepage.geturl() in urlarchive: 
       break; 
      else: 
       urlarchive.append(thepage.geturl()); 
       print(pager); 
     except: 
      break; 
     soup = BeautifulSoup(thepage, "html.parser") 

     for link in soup.findAll('blockquote'): 
      sanitized = link.find('p').text.strip() 
      spantext = link.find('a') 
      writer = spantext.find('span').text 
      print(sanitized) 
      print(writer) 
      print('---------------------------------------------------------') 


     pager += 1 

category_crawler() 
Verwandte Themen