Pelikan666
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
Hallo Community, mit diesem Code übertrage ich die jeweilige Tabelle in eine CSV-File: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import requests as req
from bs4 import BeautifulSoup
import csv
import pandas as pd
urls = ["https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million",
"https://www.nationmaster.com/country-info/stats/Agriculture/Agricultural-growth",
"https://www.nationmaster.com/country-info/stats/Energy/Electric-power-consumption/KWh"]
for url in urls:
r = req.get(url)
soup = BeautifulSoup(r.content, 'html.parser')
table = soup.find_all('table')[0]
df = pd.read_html(str(table))[0]
countries = df["COUNTRY"].tolist()
users = df["AMOUNT"].tolist()
with open("2.csv", 'a', newline='')as f:
writer = csv.writer(f)
for element in countries, users:
writer.writerow(element)
|
Nun stellen sich mir folgende Fragen: 1.) Gibt es eine Alternative zu meinem Code, die auch mehrere Tabellen von mehreren Websiten übernimmt ? Mit 1
2
3
4
5
6
7
8
9
10
11
12
13 | import csv
import pandas as pd
urls = ["https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million",
"https://www.nationmaster.com/country-info/stats/Agriculture/Agricultural-growth",
"https://www.nationmaster.com/country-info/stats/Energy/Electric-power-consumption/KWh"]
for url in urls:
r = pd.read_html(url)
with open("2.csv", 'a', newline='')as f:
writer = csv.writer(f)
for element in r:
writer.writerow(element)
|
werden u.a. nur "AMOUNT", "COUNTRY" übernommen, aber nicht der Tabelleninhalt. 2.) Angenommen, es existiert neben "AMOUNT" und "COUNTRY", auch "A", "B", "C", allerdings nicht in jeder Tabelle. Bsp.: 1. url:"AMOUNT", "COUNTRY", "A", "B", "C" 2. url:"AMOUNT", "COUNTRY", "A", "C" 3. url:"AMOUNT", "COUNTRY", "B", "C" Was muss an dem Code geändert werden, dass auch zusätzlich "A", "B", "C" übernommen wird. Ich hätte an eine if-Schleife Gedacht, die die Existenz von "A", "B", "C" prüft und wenn vorhanden, diese dann übernimmt. 3.) Wie wird "COUNTRY" alphabetisch sortiert und übernommen ? LG
|
Axel-Erfurt
Anmeldungsdatum: 18. Mai 2016
Beiträge: 1347
|
Beispiel f. https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | import pandas as pd
import requests
from bs4 import BeautifulSoup
import os
from sys import platform
url_cntr = 'https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million'
t = requests.get(url_cntr)
html_content = t.content
html_soup = BeautifulSoup(html_content, 'html.parser')
sov_tables = html_soup.find('table')
df = pd.read_html(str(sov_tables))
df = df[0]
print(df)
with open('/tmp/table.csv', 'w') as f:
df.to_csv(f, sep='\t', encoding='utf-8', index=False)
if platform == "linux" or platform == "linux2":
os.system("xdg-open /tmp/table.csv")
|
|
Pelikan666
(Themenstarter)
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
Die Antwort beantwortet keinerlei meiner Probleme. Trotzdem Danke.
|
Pelikan666
(Themenstarter)
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
Verzeihung, es sollte heißen: Sie sind der Beste, die Antwort ist ideal !
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29067
Wohnort: WW
|
Hallo, @Axel-Erfurt: os.system ist veraltet, dass steht sogar wörtlich in der Python-Doku. Das subprocess Modul ist der Stand der Dinge.
Gruß, noisefloor
|
Axel-Erfurt
Anmeldungsdatum: 18. Mai 2016
Beiträge: 1347
|
Wir wollen doch jetzt keine Korinthenkackerei anfangen, os.system funktioniert immer noch. In den Ubuntu Quellen sind doch auch völlig veraltete Versionen, z.B. Pyqt5 wo dann eben manches nicht funktioniert.
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29067
Wohnort: WW
|
Hallo,
os.system funktioniert immer noch
Darum geht es nicht. Du propagierst ein Vorgehen, was selbst in der offiziellen Python-Doku als explizit als veraltet bezeichnet wird. Bringt keinen weiter. Eines der Kernproblem von Lernenden mit Python ist ja, dass es im Netz bergeweise veraltete und falsche Anleitungen gibt. Da brauchen wir hier nicht noch aktiv zu beitragen, dass der Zustand nicht besser wird. Gruß, noisefloor
|
Pelikan666
(Themenstarter)
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
So, ich habe den Code geändert: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import pandas as pd
import requests
from bs4 import BeautifulSoup
import os
from sys import platform
with open('/tmp/table.csv', 'a') as f:
for link in urls:
page = requests.get(link)
html = BeautifulSoup(page.content, 'html.parser')
tables = html.find('table')
df = pd.read_html(str(tables))
df = df[0]
df = df.sort_values(by=['COUNTRY'])
df.to_csv(f, sep='\t', encoding='utf-8', index=False)
print(df)
if platform == "linux" or platform == "linux2":
os.system("xdg-open /tmp/table.csv")
|
Jetzt erhalte ich die Tabellen der jeweiligen Webseiten. Mir ist es nicht möglich, wie in //pandas.pydata.org/pandas-docs/stable/user_guide/reshaping.html: und //pandas.pydata.org/pandas-docs/stable/reference/frame.html#combining-joining-merging: gezeigt, die Werte "AMOUNT" , "DATE" ,... der zweiten Tabelle, der ersten Tabelle zuzuordnen. Heißt konkret: | COUNTRY AMOUNT AMOUNT DATE DATE
Afghanistan 1.86 million 0.0 1993 2006
|
ODER
| COUNTRY AMOUNT DATE AMOUNT DATE
Afghanistan 1.86 million 1993 0.0 2006
|
Hat jemand eine anfängerfreundliche Lösung für beide Wunschlösungen ? LG
|
Pelikan666
(Themenstarter)
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
| urls = ['https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million',
'https://www.nationmaster.com/country-info/stats/Education/Children-out-of-school,-primary']
|
|
Axel-Erfurt
Anmeldungsdatum: 18. Mai 2016
Beiträge: 1347
|
Ich gehe davon aus das Du GRAPH nicht benötigst.
Für deinen Spezialwunsch müsstest Du extra column anlegen. Das ergibt eine Tabelle (1.Sortierung nach COUNTRY und 2.Sortierung nach DATE) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | import pandas as pd
from subprocess import Popen
import os
csvFile = "/tmp/table.csv"
mlist = []
if os.path.isfile(csvFile):
os.remove(csvFile) # alte datei löschen
urls = ['https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million',
'https://www.nationmaster.com/country-info/stats/Education/Children-out-of-school,-primary']
for link in urls:
df = pd.read_html(link, header=0, flavor='bs4')[0]
df = df[['COUNTRY', 'AMOUNT', 'DATE']]
df = df.sort_values(by=['COUNTRY'])
for index, rows in df.iterrows():
my_list =[rows.COUNTRY, rows.AMOUNT, rows.DATE]
mlist.append(my_list)
df2 = pd.DataFrame(mlist)
df2.columns = ['COUNTRY', 'AMOUNT', 'DATE']
df2 = df2.sort_values(['COUNTRY', 'DATE'], ascending=[True, True])
print(df2)
with open(csvFile, 'a') as f:
df2.to_csv(f, sep='\t', encoding='utf-8', index=False)
p = Popen(["xdg-open", csvFile])
|
|
Axel-Erfurt
Anmeldungsdatum: 18. Mai 2016
Beiträge: 1347
|
Hier noch eine Version mit zusätzlichen Spalten: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | import pandas as pd
from subprocess import Popen
import os
from operator import itemgetter
csvFile = "/tmp/table.csv"
mlist = []
if os.path.isfile(csvFile):
os.remove(csvFile) # alte datei löschen
urls = ['https://www.nationmaster.com/country-info/stats/Sports/Chess/GrandMasters-per-million',
'https://www.nationmaster.com/country-info/stats/Education/Children-out-of-school,-primary']
for link in urls:
df = pd.read_html(link, header=0, flavor='bs4')[0]
df = df[['COUNTRY', 'AMOUNT', 'DATE']]
df = df.sort_values(by=['COUNTRY'])
for index, rows in df.iterrows():
my_list =[rows.COUNTRY, rows.AMOUNT, rows.DATE]
mlist.append(my_list)
mlist2 = sorted(mlist, key=itemgetter(0))
mlist3 = []
for x in range(len(mlist2) - 1):
if mlist2[x][0] == mlist2[x+1][0]:
firstline = "%s\t%s\t%s" % (str(mlist2[x][0]), str(mlist2[x][1]), str(mlist2[x][2]))
secondline = "%s\t%s" % (str(mlist2[x+1][1]), str(mlist2[x+1][2]))
all = "%s\t%s" % (firstline, secondline)
mlist3.append(all.split('\t'))
df2 = pd.DataFrame(mlist3)
df2.columns = ['COUNTRY', 'AMOUNT', 'DATE', 'AMOUNT 2', 'DATE 2']
df2 = df2.sort_values(['COUNTRY'], ascending=[True])
print(df2)
with open(csvFile, 'a') as f:
df2.to_csv(f, sep='\t', encoding='utf-8', index=False)
p = Popen(["xdg-open", csvFile])
|
COUNTRY AMOUNT DATE AMOUNT 2 DATE 2
0 Afghanistan 0.0 2006 1.86 million 1993
1 Albania 0.315 2006 22232 2003
2 Algeria 0.0 2006 25337 2012
3 Angola 0.0 2006 512918 2011
|
Pelikan666
(Themenstarter)
Anmeldungsdatum: 22. September 2019
Beiträge: 19
|
Vielen Dank, wieder was gelernt. Deinen Code verstehe ich. Was ist, wenn sich jeden Tag die Spalten auf der Webseite ändern,ich nicht weiß, ob DATE, COUNTRY oder AMOUNT vorhanden ist und ich nicht jedes mal den Code ändern will, um die Tabelle zu erhalten ? Gibt es dafür auch eine anfängerfreundliche Lösung ?
Sowas wie "df = df[['Alle Spalten die vorhanden sind']]"
|
Axel-Erfurt
Anmeldungsdatum: 18. Mai 2016
Beiträge: 1347
|
Mit | if os.path.isfile(csvFile):
os.remove(csvFile) # alte datei löschen
|
wird ja die alte Tabelle gelöscht, mit dem Aufruf des Scripts erhältst Du also immer die neuesten Werte als Tabelle.
|