2017-02-27 1 views
-3

Je travaille sur un grattoir depuis un petit moment et je suis très proche de l'avoir fait fonctionner comme prévu. Mon code comme suit:Python grattoir conseils

import urllib.request 
from bs4 import BeautifulSoup 


# Crawls main site to get a list of city URLs 
def getCityLinks(): 
    city_sauce = urllib.request.urlopen('https://www.prodigy-living.co.uk/') # Enter url here 
    city_soup = BeautifulSoup(city_sauce, 'html.parser') 
    the_city_links = [] 

    for city in city_soup.findAll('div', class_="city-location-menu"): 
     for a in city.findAll('a', href=True, text=True): 
      the_city_links.append('https://www.prodigy-living.co.uk/' + a['href']) 
    return the_city_links 

# Crawls each of the city web pages to get a list of unit URLs 
def getUnitLinks(): 
    getCityLinks() 
    for the_city_links in getCityLinks(): 
     unit_sauce = urllib.request.urlopen(the_city_links) 
     unit_soup = BeautifulSoup(unit_sauce, 'html.parser') 
     for unit_href in unit_soup.findAll('a', class_="btn white-green icon-right-open-big", href=True): 
      yield('the_url' + unit_href['href']) 

the_unit_links = [] 
for link in getUnitLinks(): 
    the_unit_links.append(link) 

# Soups returns all of the html for the items in the_unit_links 


def soups(): 
    for the_links in the_unit_links: 
     try: 
      sauce = urllib.request.urlopen(the_links) 
      for things in sauce: 
       soup_maker = BeautifulSoup(things, 'html.parser') 
       yield(soup_maker) 
     except: 
      print('Invalid url') 

# Below scrapes property name, room type and room price 

def getPropNames(soup): 
    try: 
     for propName in soup.findAll('div', class_="property-cta"): 
      for h1 in propName.findAll('h1'): 
       print(h1.text) 
    except: 
     print('Name not found') 

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


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

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

Lorsque je lance ceci, il renvoie tous les prix pour toutes les URL ramassées. Cependant, je ne retourne pas les noms ou les chambres et je ne sais pas vraiment pourquoi. J'apprécierais vraiment n'importe quel pointeur sur ceci, ou les manières d'améliorer mon code - apprenant Python pendant quelques mois maintenant!

+0

pour exploration du Web en python, je recommande fortement d'utiliser [ 'scrapy '] (https://scrapy.org) – eLRuLL

+0

Que retourne-t-il à la place? – ryugie

+0

également, cela dépend totalement du site que vous explorez, et sans partager cette information, nous ne pouvons pas savoir si ce que vous analysez est correct. – eLRuLL

Répondre

1

Je pense que les liens que vous êtes en train de gratter vont vous rediriger vers un autre site web, auquel cas vos fonctions de grattage ne seront pas utiles! Par exemple, le lien pour une salle à Birmingham vous redirige vers un autre site Web.

En outre, soyez prudent dans votre utilisation des méthodes find et find_all en BS. Le premier renvoie une seule balise (comme lorsque vous voulez un nom de propriété) tandis que find_all() renvoie une liste vous permettant d'obtenir, par exemple, plusieurs prix et types de pièces.

De toute façon, j'ai un peu simplifié votre code et c'est ainsi que j'ai rencontré votre problème. Peut-être que vous voulez vous inspirer de cette:

import requests 
from bs4 import BeautifulSoup 

main_url = "https://www.prodigy-living.co.uk/" 

# Getting individual cities url 
re = requests.get(main_url) 
soup = BeautifulSoup(re.text, "html.parser") 
city_tags = soup.find("div", class_ = "footer-city-nav") # Bottom page not loaded dynamycally 
cities_links = [main_url+tag["href"] for tag in city_tags.find_all("a")] # Links to cities 


# Getting the individual links to the apts 
indiv_apts = [] 

for link in cities_links[0:4]: 
    print "At link: ", link 
    re = requests.get(link) 
    soup = BeautifulSoup(re.text, "html.parser") 
    links_tags = soup.find_all("a", class_ = "btn white-green icon-right-open-big") 

    for url in links_tags: 
     indiv_apts.append(main_url+url.get("href")) 

# Now defining your functions 
def GetName(tag): 
    print tag.find("h1").get_text() 

def GetType_Price(tags_list): 
    for tag in tags_list: 
     print tag.find("h5").get_text() 
     print tag.find("p", class_ = "room-price").get_text() 

# Now scraping teach of the apts - name, price, room. 
for link in indiv_apts[0:2]: 
    print "At link: ", link 
    re = requests.get(link) 
    soup = BeautifulSoup(re.text, "html.parser") 
    property_tag = soup.find("div", class_ = "property-cta") 
    rooms_tags = soup.find_all("div", class_ = "featured-item") 
    GetName(property_tag) 
    GetType_Price(rooms_tags) 

Vous verrez que à droite au deuxième élément de la lis, vous obtiendrez un AttributeError que vous n'êtes pas sur votre page de site Web plus. En effet:

>>> print indiv_apts[1] 
https://www.prodigy-living.co.uk/http://www.iqstudentaccommodation.com/student-accommodation/birmingham/penworks-house?utm_source=prodigylivingwebsite&utm_campaign=birminghampagepenworksbutton&utm_medium=referral # You will not scrape the expected link right at the beginning 

La prochaine fois venir avec un problème précis à résoudre, ou dans un autre cas, il suffit de prendre un coup d'œil à la section de révision du code.

Sur find et find_all: https://www.crummy.com/software/BeautifulSoup/bs4/doc/#calling-a-tag-is-like-calling-find-all

Enfin, je pense qu'il répond aussi à votre question ici: https://stackoverflow.com/questions/42506033/urllib-error-urlerror-urlopen-error-errno-11001-getaddrinfo-failed

cheers :)

+0

Merci pour cela, je ne m'attendais pas à ce que quelqu'un le réécrive, mais cela fonctionne parfaitement! J'ai ajouté un 'try' et' except 'et il fonctionne comme prévu. – Maverick

+0

Heureux d'aider :) Je vérifie toujours brièvement ce qui est dans une liste avant de l'itérer – DMPierre

+0

Oui, j'avais remarqué que certains des liens redirigeaient vers un autre site avant de poster. Je veux trouver un moyen d'ajouter ceux-ci à une liste séparée. Merci encore! – Maverick