2017-02-17 25 views
0

Я использую Python 3.5 и пытается наскрести список ссылок (с того же сайта), код следующим образом:Зачистка список адресов

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() 

До сих пор, если я печатаю суп, получить propNames, getPrice или getRoom они, похоже, работают. Но я не могу заставить его пройти через каждый URL-адрес и распечатать getPropNames, getPrice и getRoom.

Только учу Python несколько месяцев, поэтому очень признателен за помощь в этом, пожалуйста!

ответ

0

Только подумайте, что этот код делать:

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 

Позвольте мне показать вам пример:

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

И выход для url_list = ['one', 'two', 'three'] является:

one 
('one', 'a') 

Вы видите сейчас ? Что происходит?

В основном ваша функция возврата супа возвращается на первый return - не возвращать ни один итератор, ни один список; только первый BeautifulSoup - вам повезет (или нет), что это итерацию :)

Так изменить код:

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 

И тогда выход:

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

Но я считаю, что это тоже не сработает :) Просто интересно, что возвращается соус: sauce = urllib.request.urlopen(url) и на самом деле на ваш код итерации: for things in sauce - значит, что такое things.

Счастливое кодирование.

+0

Спасибо за то, что Себастьян Опалчиньски, я возьму это на борту, постараюсь обнять его и сообщить об итогах! – Maverick

0

В каждой из функций get* используется глобальная переменная soup, которая не установлена ​​правильно нигде. Даже если бы это было так, это не было бы хорошим подходом. Сделать soup аргумент функции вместо этого, например .:

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) 

Во-вторых, вы должны быть делать yield из soup() вместо return, чтобы превратить его в генератор. В противном случае вам нужно будет вернуть список объектов BeautifulSoup.

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 

Я также предлагаю использовать XPath или CSS селекторы для извлечения HTML элементов: https://stackoverflow.com/a/11466033/2997179.

+0

Спасибо, Мартин Валгур, это проницательно - я посмотрю в Xpath/CSS. При применении вашего предложения я получаю следующее сообщение об ошибке: AttributeError: объект 'function' не имеет атрибута 'findAll - любые идеи? – Maverick

+1

Вы добавили параметр 'soup' ко всем функциям? Я предлагаю также переименовать функцию 'суп()' в 'супы()'. –

+0

Спасибо, это было, если бы я ошибся! Однако, похоже, это работает только для getPrice. Остальные 2 ничего не возвращают?Как ни странно, когда я впервые написал эти функции, я использовал 1 url, и все они отлично работали. – Maverick