2017-02-17 13 views
0

Ich verwende Python 3.5 und versuchen, eine Liste von URLs zu kratzen (von der gleichen Website), Code wie folgt:Scraping eine Liste von URLs

import urllib.request 
from bs4 import BeautifulSoup 



url_list = ['URL1', 
      'URL2','URL3] 

def soup(): 
    for url in url_list: 
     sauce = urllib.request.urlopen(url) 
     for things in sauce: 
      soup_maker = BeautifulSoup(things, 'html.parser') 
      return soup_maker 

# Scraping 
def getPropNames(): 
    for propName in soup.findAll('div', class_="property-cta"): 
     for h1 in propName.findAll('h1'): 
      print(h1.text) 

def getPrice(): 
    for price in soup.findAll('p', class_="room-price"): 
     print(price.text) 

def getRoom(): 
    for theRoom in soup.findAll('div', class_="featured-item-inner"): 
     for h5 in theRoom.findAll('h5'): 
      print(h5.text) 


for soups in soup(): 
    getPropNames() 
    getPrice() 
    getRoom() 

Bisher wenn ich Suppe drucken, erhalten propNames, getPrice oder getRoom scheinen sie zu arbeiten. Aber ich kann es anscheinend nicht durch jede der URLs gehen lassen und getPropNames, getPrice und getRoom ausdrucken.

Erst seit ein paar Monaten Python lernen, also würde ich bitte einige Hilfe mit diesem bitte sehr schätzen!

Antwort

0

Man denke nur, was dieser Code tun:

def soup(): 
    for url in url_list: 
     sauce = urllib.request.urlopen(url) 
     for things in sauce: 
      soup_maker = BeautifulSoup(things, 'html.parser') 
      return soup_maker 

Lassen Sie mich Ihnen ein Beispiel:

def soup2(): 
    for url in url_list: 
     print(url) 
     for thing in ['a', 'b', 'c']: 
      print(url, thing) 
      maker = 2 * thing 
      return maker 

Und der Ausgang für url_list = ['one', 'two', 'three'] ist:

one 
('one', 'a') 

Siehst du jetzt ? Was ist los?

Grundsätzlich Ihre Suppe Funktion zurück auf ersten return - keine Iterator, keine Liste zurückgeben; nur der erste BeautifulSoup - Sie Glück haben (oder auch nicht), dass dies iterable :)

So ändern Sie den Code:

def soup3(): 
    soups = [] 
    for url in url_list: 
     print(url) 
     for thing in ['a', 'b', 'c']: 
      print(url, thing) 
      maker = 2 * thing 
      soups.append(maker) 
    return soups 

Und dann Ausgabe lautet:

one 
('one', 'a') 
('one', 'b') 
('one', 'c') 
two 
('two', 'a') 
('two', 'b') 
('two', 'c') 
three 
('three', 'a') 
('three', 'b') 
('three', 'c') 

Aber ich glaube, das wird auch nicht funktionieren :) Fragen Sie sich einfach, was von Soße zurückgegeben wird: sauce = urllib.request.urlopen(url) und tatsächlich auf was Ihr Code iteriert: for things in sauce - was ist die things ist.

Glückliche Kodierung.

+0

Danke für diesen Sebastian Opałczyński, ich werde das an Bord nehmen, versuchen, meinen Kopf drumherum zu bekommen, und Sie das Ergebnis wissen lassen! – Maverick

0

Jede der get*-Funktionen verwendet eine globale Variable soup, die nirgendwo richtig festgelegt ist. Selbst wenn es so wäre, wäre das kein guter Ansatz. Machen soup ein Funktionsargument statt, z.B .:

def getRoom(soup): 
    for theRoom in soup.findAll('div', class_="featured-item-inner"): 
     for h5 in theRoom.findAll('h5'): 
      print(h5.text) 

for soup in soups(): 
    getPropNames(soup) 
    getPrice(soup) 
    getRoom(soup) 

Zweitens sollten Sie yield von soup() statt return tun wird es in einen Generator einzuschalten. Andernfalls müssten Sie eine Liste der BeautifulSoup Objekte zurückgeben.

def soups(): 
    for url in url_list: 
     sauce = urllib.request.urlopen(url) 
     for things in sauce: 
      soup_maker = BeautifulSoup(things, 'html.parser') 
      yield soup_maker 

Ich würde auch vorschlagen, Selektoren mit XPath oder CSS HTML-Elemente zu extrahieren: https://stackoverflow.com/a/11466033/2997179.

+0

Danke Martin Valgur, das ist aufschlussreich - ich werde in Xpath/CSS schauen. Bei der Anwendung Ihres Vorschlags erhalte ich folgende Fehlermeldung: AttributeError: Objekt 'function' hat kein Attribut 'findAll - irgendwelche Ideen? – Maverick

+1

Haben Sie den Parameter 'suppen' allen Funktionen hinzugefügt? Ich empfehle auch, die Funktion 'supp()' in 'suppen()' umzubenennen. –

+0

Danke, das war, wo ich falsch liege! Es scheint jedoch nur für getPrice zu funktionieren. Die anderen 2 geben nichts zurück?Seltsam, als ich diese Funktionen zum ersten Mal schrieb, benutzte ich 1 URL und sie alle funktionierten perfekt. – Maverick