WebScraping Problem ze zmiennymi

0

Cześć, siedzę już od 2 godzin nad poniższym kodem i nie wiem co jest nie tak. Otóż próbuję przeprowadzi webscraping, strony otodom.pl, który wyszukuje informację o mieszkaniach itp. Kod wywala błąd który brzmi następująco**:'NoneType' object has no attribute 'text'**.

  • Próbowałem zamiast 'lxml' zmienić na 'html-parser'= bez zmian,
  • Próbowałem dodać lstrip, bo w niektórych zmiennych jak np cena jest oznaczenie 'zł ', zaś w powierzchnia jest oznaczenie 'm2' = bez zmian
  • Próbowałem usunąć .text, i zmienne się wczytują ale z wartością 'None'

Chcę jeszcze nadmienić iż class_= dla wszystkich zmiennych opisanych powyżej wygląda identycznie na każdej stronie. Dla pojedynczych zmiennych printuje się dobrze z funkcją text.strip()

Mój kod:

import requests
from bs4 import BeautifulSoup
import pandas as pd

baseurl='https://www.otodom.pl/sprzedaz/mieszkanie/'

headers={
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
}

houselinks=[]
for x in range(10,12):
    r=requests.get(f'https://www.otodom.pl/sprzedaz/mieszkanie/?page={x}')
    soup=BeautifulSoup(r.content, 'lxml')
    houselist=soup.find_all('div',class_='col-md-content section-listing__row-content')
    for item in houselist:
        for link in item.find_all('a', href=True):
            houselinks.append(baseurl+ link['href'])

            
#testlink = 'https://www.otodom.pl/pl/oferta/uroczysko-mieszkanie-53-09m2-2-pokoje-z-ogrodem-ID48Nos.html#ab04badaa0'
houselist=[]
for link in houselinks:
    r=requests.get(link,headers=headers)
    soup=BeautifulSoup(r.content, 'lxml')

    name=soup.find('h1', class_='css-11t1qm5').text.strip()
    cena=soup.find('strong',class_='css-1mojccp').text.strip()
    perMetr=soup.find('div',class_='css-4ak5ev').text.strip()
    powierzchnia=soup.find('div', class_='css-1s5nyln').text.strip()
    adres=soup.find('a',class_='css-1rg0v62').text.strip()
    rooms={
        'name':name,
        'cena':cena,
        'perMetr':perMetr,
        'powierzchnia':powierzchnia,
        'adres':adres
    }
    print(rooms)
0

Otwórz narzędzia deweloperskie w Chrome, inspekt element i sprawdź czy te obiekty istnieją.

0

Nie masz tam czasem złego selectora klasy?

Bo używasz kilku klas do wybrania diva, więc raczej powinieneś używać prawidłowego selectora

1

Na szybko -> dziala i wyszukuje wszystkie elementy. Byc moze szukasz w zlym parent elemencie.

from requests_html import HTMLSession
class scrap(HTMLSession):
    def __init__(self):
        HTMLSession.__init__(self)
        self.link = "https://www.otodom.pl/pl/oferta/nowy-magistrat-2-pokoje-34-65-mkw-ID42HBE.html#ab04badaa0"
    
    def _get_content(self):
        return self.get(self.link).html.find("main", first=True)
    
    def content_text(self, selectors):
        for x in selectors:
            element = self._get_content().find(f"*[class*='{x}']", first=True)
            print(element.text)



selectors = ["css-11t1qm5", "css-1mojccp", "css-4ak5ev", "css-1s5nyln", "css-1rg0v62"]
s = scrap()
s.content_text(selectors)

EDIT: Dobra praktyka w BS4 jest uzywanie Select na parent element i dopiero potem z jego poziomu szukasz reszty. Wtedy powinno zadzialac :) Niemniej reguests html jest latwiejszym rozwiazaniem.

0

@lion137: Tak, wszystkie obiekty istnieją

0
lion137 napisał(a):

Otwórz narzędzia deweloperskie w Chrome, inspekt element i sprawdź czy te obiekty istnieją.

Tak, wszystkie obiekty istnieją

0

@urke: Co masz dokładnie na myśli, używam diva, bo każdy element wymienione przeze mnie wyżej jest w divie , i w klasie o takiej nazwie którą napisałem wyżej.

0

@ledi12: Dzięki za odpowiedź, ale wołałbym dojść do tego co w moim kodzie jest źle i spróbować to naprawić.

0

@ledi12: błąd leży chyba gdzieś indziej, elementy chyba się szukają dobrze, bo printowanie zwraca prawidłowe wartości:

import requests
from bs4 import BeautifulSoup
import pandas as pd

baseurl='https://www.otodom.pl/sprzedaz/mieszkanie/'

headers={
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
}

houselinks=[]
for x in range(10,12):
    r=requests.get(f'https://www.otodom.pl/sprzedaz/mieszkanie/?page={x}')
    soup=BeautifulSoup(r.content, 'lxml')
    houselist=soup.find_all('div',class_='col-md-content section-listing__row-content')
    for item in houselist:
        for link in item.find_all('a', href=True):
            houselinks.append(baseurl+ link['href'])

            
testlink = 'https://www.otodom.pl/pl/oferta/uroczysko-mieszkanie-53-09m2-2-pokoje-z-ogrodem-ID48Nos.html#ab04badaa0'

r=requests.get(testlink,headers=headers)
soup=BeautifulSoup(r.content, 'lxml')

name=soup.find('h1', class_='css-11t1qm5').text.strip()
cena=soup.find('strong',class_='css-1mojccp').text.strip()
perMetr=soup.find('div',class_='css-4ak5ev').text.strip()
powierzchnia=soup.find('div', class_='css-1s5nyln').text.strip()
adres=soup.find('a',class_='css-1rg0v62').text.strip()
print(name)

to jest kod bez zastosowania poniższego:


for link in houselinks:
    r=requests.get(link,headers=headers)
0

Jak Ci pisałem, obczaj sobie DOM w narzędziach deweloperskich.

0

@lion137: wszystkie obiekty się tam znajdują

0

To nie ma wyjścia, musisz to przeanalizować; nie ma lekko.

0

Ok przepisalem kod na bs4. Sproboj szukac elementow po atrybucie w stylu "element", {"class":"cos"}. Tu masz przyklad. Dziala. bs4 czasami nie wylapuje elementow w klasyczny sposob.

from bs4 import BeautifulSoup
import requests
class scraper(BeautifulSoup):
        def __init__(self, link=None):
                self.link = link
                BeautifulSoup.__init__(self, self._get_body(self.link), "lxml")
        
        def _get_body(self, link):
                return requests.get(self.link).text
               
        def _get_parent(self):
                return self.select("main")[0]
        
        def get_elements(self, selectors):
                for k,v in selectors.items():
                        print(self._get_parent().find(k, {"class":v}).text)


selectors = {"h1":"css-11t1qm5", "strong":"css-1mojccp", 
"div":"css-4ak5ev", "div":"css-1s5nyln", "a":"css-1rg0v62"}

s = scraper(link="https://www.otodom.pl/pl/oferta/nowy-magistrat-2-pokoje-34-65-mkw-ID42HBE.html#ab04badaa0")
s.get_elements(selectors)
0

@ledi12: Kurczę wiecie co chłopaki, wygląda na to, że program tych obiektów nie widzi print() nic nie wyświetla

import requests
from bs4 import BeautifulSoup
import pandas as pd

baseurl='https://www.otodom.pl/sprzedaz/mieszkanie/'

headers={
'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'
}

houselinks=[]
for x in range(10,11):
    r=requests.get(f'https://www.otodom.pl/sprzedaz/mieszkanie/?page={x}')
    soup=BeautifulSoup(r.content, 'lxml')
    houselist=soup.find_all('div',{'class':'col-md-content section-listing__row-content'})
    for item in houselist:
        for link in item.find_all('a', href=True):
            houselinks.append(baseurl+ link['href'])

            
#testlink = 'https://www.otodom.pl/pl/oferta/uroczysko-mieszkanie-53-09m2-2-pokoje-z-ogrodem-ID48Nos.html#ab04badaa0'
houselist=[]
for link in houselinks:
    r=requests.get(link,headers=headers)
    soup=BeautifulSoup(r.content, 'lxml')

    name=soup.find("h1", {"class":"css-11t1qm5"})
    cena=soup.find("strong",{"class":"css-1mojccp"})
    perMetr=soup.find("div",{"class":"css-4ak5ev"})
    powierzchnia=soup.find("div", {"class":"css-1s5nyln"})
    adres=soup.find("a",{"class":"css-1rg0v62"})
    if None in (name, cena, perMetr, powierzchnia, adres):
        continue
    print(name.text.strip())
    print(cena.text.strip())
    print(perMetr.text.strip())
    print(powierzchnia.text.strip())
    print(adres.text.strip())
    print()
0

@ledi12: Chyba już się zorientowałem o co ci chodzi, błąd jest tutaj tak ? :

  houselist=soup.find_all('div',{'class':'col-md-content section-listing__row-content'})

w sensie szuka elementu którego nie ma, znaczy ja widzę że szuka gdzieś gdzie tego nie ma, tylko nie wiem w którym miejscu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1