Scraping CODE

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nexuz89
User
Beiträge: 18
Registriert: Montag 27. Juli 2020, 10:59

Hallo zusammen

leider hab ich nach meinem Letzen Post keine Antwort bekommen und versuche es nochmal :D

Ich versuche aus einer Homepage die Menge und den Hersteller zu scraping, leider schaffe ich das nicht.

Mein momentaner code

Code: Alles auswählen

import requests
from bs4 import BeautifulSoup
import csv
import pandas as pd
from time import sleep
 
 
def connect():
    try:
        requests.get('http://google.com') #Python 3.x
        return True
    except:
        return False
def gernate_file():
    headers_text = []
    headers_text.append('Article Number')
    headers_text.append('Title')
    headers_text.append('Menge')
    headers_text.append('Hersteller')
    headers_text.append('Price')
    headers_text.append('Categorie')
    headers_text.append('Link')
    headers_text.append('Image Url')
    headers_text.append('Article Number')
 
    df = pd.DataFrame([], columns=headers_text)
    df.to_csv('Results.csv', index=False, encoding='utf-8-sig')
def hasNumbers(inputString):
    return any(char.isdigit() for char in inputString)
# url='https://www.apo-rot.de/details/bullrich-salz-tabletten/2535395.html?_menuid=7688429&_nav=verdauung_harnwege__organe.magen_darm__verdauung.sodbrennen.zur_schnellen_linderung.tabletten__kapseln'
def profileScraper(url,index):
    while(not connect()):
        print('no internet')
        sleep(5)
    res= requests.get(url)
    soup=BeautifulSoup(res.content,features='html.parser')
     
     
    title=soup.find('span',class_='hidden-xs')
    if title is not None:
        title=title.text.strip()
    else:
        return 0
    print(title)
     
     
    Hersteller=soup.find_next('div',class_='col-xs-8')
    if Hersteller is not None:
        Hersteller=Hersteller.text.strip()
    else:
        Hersteller='N/A'
    print(Hersteller)
     
     
    Price=soup.find('span',class_='')
    if Price is not None:
        Price = Price.text.strip() 
    else:
        Price='N/A'
    print(Price)
     
    Categories=soup.find_all('a',class_='overflow-hidden')
    if len(Categories) >0:
        # print(Categories[2].text.strip())
        Categories = Categories[0].text.strip()
    else:
        # print(Categories[-2].text.strip())
        Categories = Categories[-2].text.strip()
    print(url)
     
     
     
    Menge=soup.find('div',{'data-sourcefile':'details_info-standard-details.jsp'}).find_all('div',{'class':'col-xs-4 bold'})
    for element in Menge:
        if "Menge:" in element.text:
            Menge = element.find_next('div',{'class':'col-xs-8'}).text.strip()
    print(f"Menge: {Menge}")
     
 
    img_tag1=soup.find('div',class_='details_image')
    if img_tag1 is not None:
        img_tag = img_tag1.find('img',class_='img-responsive')
        if img_tag is not None:   
            img_url=img_tag['src']
            img_url_text=img_url.replace('//','')
    print(img_url_text)
         
         
     
    article_no = soup.find('div',class_='col-xs-8')
    if article_no is not None:
        article_no=article_no.text.strip()
    print(article_no)
     
    return[index,title,'`'+Menge,Hersteller,Price,Categories,url,img_url_text,article_no]
#Migrolist.csv
with open('Ikea.csv', 'r', encoding='utf-8') as readFile:
    reader = csv.reader(readFile)
    file_lines = list(reader)
 
# print(file_lines[1][8])
gernate_file()
for index, row in enumerate(file_lines[1:]): 
    print(index)
    # print(row[7])
    record=[]
    record =  profileScraper(row[6],index+1)
    df = pd.DataFrame([record])
    df.to_csv('Ikea1.csv', index=False, mode='a',  encoding='utf-8-sig', header=False)
    # break
print()
print()
# print(record)
Wäre um Hilfe sehr dankbar

Vielen dank schon mal im Voraus
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Wie man an den Hersteller und die Menge kommt habe ich dir bereits gezeigt. Das einbauen müsstest du selber hinbekommen.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Und was ist jetzt die konkrete Frage? Bei was soll man Dir helfen?

Etwas mehr Leerraum zwischen den Funktionen würde die Lesbarkeit erhöhen. Variablennamen und Funktionen schreibt man nach Konvention komplett klein.
Die connect-Funktion ist unsinnig. Nur weil google erreichbar ist, heißt das ja noch lange nicht, dass die eigentliche URL auch erreichbar ist.
Du missbrauchst da DataFrames für etwas, was das ganz normale csv-Modul auch könnte (das Du ja auch schon einsetzt).
`profileScraper` liefert mal 0 zurück und mal eine Liste. Das sollte aber immer den selben Datentyp liefern.
record wird erst an eine leere Liste gebunden und dann gleich an den Rückgabewert von profileScraper. Das erste macht daher keinen Sinn.

Code: Alles auswählen

import requests
from bs4 import BeautifulSoup
import csv
from time import sleep

HEADER = ['Article Number', 'Title', 'Menge', 'Hersteller', 'Price', 'Categorie', 'Link', 'Image Url', 'Article Number']

def has_numbers(string):
    return any(char.isdigit() for char in string)

def profile_scraper(url, index):
    while True:
        try:
            res = requests.get(url)
            break
        except requests.RequestException:
            # ignore any error
            sleep(5)
    soup = BeautifulSoup(res.content, features='html.parser')
    title = soup.find('span', class_='hidden-xs')
    if title is None:
        return [0]
    title = title.text.strip()
    print(title)
     
    hersteller = soup.find_next('div', class_='col-xs-8')
    hersteller = hersteller.text.strip() if hersteller is not None else 'N/A'
    print(hersteller)

    price = soup.find('span', class_='')
    price = price.text.strip() if price is not None else 'N/A'
    print(price)
     
    categories = soup.find_all('a', class_='overflow-hidden')
    if len(categories) > 0:
        categories = categories[0].text.strip()
    else:
        # TODO: das macht keinen Sinn
        raise IndexError()

    mengen = soup.find('div', {'data-sourcefile':'details_info-standard-details.jsp'}).find_all('div', {'class':'col-xs-4 bold'})
    for element in mengen:
        if "Menge:" in element.text:
            menge = element.find_next('div', {'class':'col-xs-8'}).text.strip()
    print(f"Menge: {menge}")
     
    img_tag = soup.find('div',class_='details_image')
    if img_tag is not None:
        img_tag = img_tag.find('img',class_='img-responsive')
        if img_tag is not None:   
            img_url = img_tag['src'].replace('//','')
        else:
            img_url = 'N/A'
    else:
        img_url = 'N/A'
    print(img_url)
         
    article_no = soup.find('div',class_='col-xs-8')
    article_no = article_no.text.strip() if article_no is not None else 'N/A'

    return [index, title, '`' + menge, hersteller, price, categories, url, img_url, article_no]
    

def main():
    with open('Ikea.csv', encoding='utf-8') as input:
        reader = csv.reader(input)
        _ = next(reader)
        entries = list(reader)

    with open('Ikea1.csv, 'w', encoding='utf-8') as output:
        writer = csv.writer(output)
        writer.writerow(HEADER)
        for index, entry in enumerate(entries, 1): 
            print(index)
            record =  profile_scraper(row[6], index)
            writer.writerow(record)

if __name__ = '__main__':
    main()
nexuz89
User
Beiträge: 18
Registriert: Montag 27. Juli 2020, 10:59

Vielen dank, Ich erreiche die Menge nicht und den Hersteller der Teil vom code ist nicht korrekt von mir...
nexuz89
User
Beiträge: 18
Registriert: Montag 27. Juli 2020, 10:59

ich bekomme ein syntax fehler !

C:\Users\Marcel\Downloads>apo-rot1new.py
File "C:\Users\Marcel\Downloads\apo-rot1new.py", line 78
if __name__ = '__main__':
^
SyntaxError: invalid syntax
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Der Vergleichsoperator in Python ist == nicht =.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Ich habe dir in meinem Beispiel doch gezeigt wie man an den Hersteller und die Menge kommt. Wenn du das nicht in deine riesige Funktion eingebaut bekommst, dann mach da halt eine eigene Funktion daraus, die dir den Hersteller und die Menge zurückgibt.

Code: Alles auswählen

from bs4 import BeautifulSoup
import requests
       


HEADERS = {"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0"}


def get_producer_and_quantity(soup):
    info = soup.find('div',{'data-sourcefile':'details_info-standard-details.jsp'}).find_all('div',{'class':'col-xs-4 bold'})
    for element in info:
        if "Hersteller:" in element.text:
            hersteller = element.find_next('div',{'class':'col-xs-8'}).text.strip()
        elif "Menge:" in element.text:
            menge = element.find_next('div',{'class':'col-xs-8'}).text.strip()
    return hersteller, menge

def main():
    url = "https://www.apo-rot.de/details/baldriparan-zur-beruhigung-ueberzogene-tabletten/10124803.html?_menuid=7685764&_nav=nervensystem_stress__beruhigun.beruhigung_stress__schlaf.beruhigungs__schlafmittel"
    page = requests.get(url, headers=HEADERS)
    soup = BeautifulSoup(page.content, "html.parser")
    hersteller, menge = get_producer_and_quantity(soup)
    print(f"Hersteller: {hersteller}")
    print(f"Menge: {menge}")

main()
Und so kleine Fehler wie hier sollte man schon alleine beheben können, ansonsten empfiehlt sich ein Tutorial durchzuarbeiten.
nexuz89
User
Beiträge: 18
Registriert: Montag 27. Juli 2020, 10:59

eine frage hätte ich noch ich bekomme bei der menge das ausgespuckt, `100 St wie bekomme ich den Apostroph weg ?

vielen dank für eure Hilfe hab's geschafft, vielen dank :)
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nexuz89: In dem *Du* das da nicht vorne dran stellst. 🙄
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Was hast du denn eigentlich vor? Willst du nur Title, Hersteller, Menge, Pharmazentralnummer, die Produkt URL und die Produktbild URL scrapen?
Antworten