Ich habe also einen Code, der den Namen und den Preis eines Minerals aus (bisher) 14 Seiten entfernt und in einer TXT-Datei speichert. Ich habe zuerst versucht, nur Seite1 zu verwenden, dann wollte ich weitere Seiten hinzufügen, um mehr Daten zu erhalten. Aber dann greift der Code auf etwas, das er nicht sollte – zufällige Namen/Strings. Ich hatte nicht damit gerechnet, dass es dieses Exemplar ergattern würde, aber es tat es und gab diesem Exemplar den falschen Preis! Es passiert, wenn ein Mineral diesen „unerwarteten Namen“ hat und dann der gesamte Rest der Liste den falschen Preis hat. Siehe unten:
Da sich diese Zeichenfolge von anderen Zeichenfolgen unterscheidet, kann der weitere Code sie nicht aufteilen und gibt die Fehlermeldung aus:
cutted2 = split2.pop(1) ^^^^^^^^^^^^^ IndexError: pop index out of range
Ich habe versucht, diese Fehler zu ignorieren und eine der Methoden zu verwenden, die auf verschiedenen Stackoverflow-Seiten verwendet werden:
try: cutted2 = split2.pop(1) except IndexError: continue
Es hat tatsächlich funktioniert, es sind keine Fehler aufgetreten...aber dann hat es dem falschen Mineral den falschen Preis zugewiesen (wie mir aufgefallen ist)! Wie kann ich den Code ändern, um diese „seltsamen“ Namen zu ignorieren und mit der Liste fortzufahren? Unten ist der vollständige Code. Ich erinnere mich, dass er bei URL5 angehalten hat und diesen Popup-Indexfehler ausgegeben hat:
import requests from bs4 import BeautifulSoup import re def collecter(URL): headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"} soup = BeautifulSoup(requests.get(URL, headers=headers).text, "lxml") names = [n.getText(strip=True) for n in soup.select("table tr td font a")] prices = [ p.getText(strip=True).split("Price:")[-1] for p in soup.select("table tr td font font") ] names[:] = [" ".join(n.split()) for n in names if not n.startswith("[")] prices[:] = [p for p in prices if p] with open("Minerals.txt", "a+", encoding='utf-8') as file: for name, price in zip(names, prices): # print(f"{name}\n{price}") # print("-" * 50) filename = str(name)+" "+str(price)+"\n" split1 = filename.split(' / ') cutted1 = split1.pop(0) split2 = cutted1.split(": ") try: cutted2 = split2.pop(1) except IndexError: continue two_prices = cutted2+" "+split1.pop(0)+"\n" file.write(two_prices) URL1 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=0" URL2 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=25" URL3 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=50" URL4 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=75" URL5 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=100" URL6 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=125" URL7 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=150" URL8 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=175" URL9 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=200" URL10 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=225" URL11 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=250" URL12 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=275" URL13 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=300" URL14 = "https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First=325" collecter(URL1) collecter(URL2) collecter(URL3) collecter(URL4) collecter(URL5) collecter(URL6) collecter(URL7) collecter(URL8) collecter(URL9) collecter(URL10) collecter(URL11) collecter(URL12) collecter(URL13) collecter(URL14)
EDIT: Hier ist der voll funktionsfähige Code unten, danke an den Helfer!
import requests from bs4 import BeautifulSoup import re for URL in range(0,2569,25): headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"} soup = BeautifulSoup(requests.get(f'https://www.fabreminerals.com/search_results.php?LANG=EN&SearchTerms=&submit=Buscar&MineralSpeciment=&Country=&Locality=&PriceRange=&checkbox=enventa&First={URL}', headers=headers).text, "lxml") names = [n.getText(strip=True) for n in soup.select("table tr td font>a")] prices = [p.getText(strip=True).split("Price:")[-1] for p in soup.select("table tr td font>font")] names[:] = [" ".join(n.split()) for n in names if not n.startswith("[") ] prices[:] = [p for p in prices if p] with open("MineralsList.txt", "a+", encoding='utf-8') as file: for name, price in zip(names, prices): # print(f"{name}\n{price}") # print("-" * 50) filename = str(name)+" "+str(price)+"\n" split1 = filename.split(' / ') cutted1 = split1.pop(0) split2 = cutted1.split(": ") cutted2 = split2.pop(1) try: two_prices = cutted2+" "+split1.pop(0)+"\n" except IndexError: two_prices = cutted2+"\n" file.write(two_prices)
Aber nach einigen Änderungen stoppt es mit einem neuen Fehler – es kann die Zeichenfolge anhand der angegebenen Eigenschaft nicht finden, daher der Fehler „IndexError: popping from empty list“ ... sogar soup.select("table tr td font>font" )
hat Hilfe bereitgestellt, wie es in „Name“ der Fall ist.
您可以尝试下一个示例以及分页
输出:
您只需使 CSS 选择器更加具体,以便仅识别直接位于字体元素内部(而不是向下几层)的链接:
添加进一步的条件,即链接指向单个项目而不是页面底部的下一页/上一页链接也将有所帮助: