Seite 2 von 3

Re: String-Operation

Verfasst: Mittwoch 21. August 2019, 06:26
von ThomasL
Eine gute Quelle für Tips und Tricks rund um Pandas bietet Kevin Markham auf seinem Youtube Channel https://www.youtube.com/user/dataschool/videos und auf Twitter.

Re: String-Operation

Verfasst: Mittwoch 21. August 2019, 12:00
von Strawk
Hallo Sirius3!
Dein Code vom 16.08.2019, 22.34 Uhr funktioniert insoweit nicht, als die Fehlermeldung kommt:
Zeile 32: TypeError: list indices must be integers or slices, not str
Ich würde deinen Code aber gerne weiterverwenden, da er wohl kürzer und besser ist.
Grüße
Strawk

Re: String-Operation

Verfasst: Mittwoch 21. August 2019, 13:10
von Sirius3
Zeile 32 ist das wohl ehere nicht (das nächste mal bitte den kompletten Traceback, damit ich nicht raten muß). Wahrscheinlich muß es einfach anchor[0] heißen, wenn man annimmt, dass in jeder Tabellenzelle nur jeweils ein <a> vorkommt.

Re: String-Operation

Verfasst: Mittwoch 21. August 2019, 14:10
von Strawk
Mit anchor[0] dort ergibt sich das Folgende:

runfile('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py', wdir='C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx')
Reloaded modules: geo_mk, geo_mk.geo_gpx, geo_mk.geo_distances, geo_mk.geo_utils, geo_mk.geo_visualization
Traceback (most recent call last):

File "<ipython-input-4-04c4a6166c3e>", line 1, in <module>
runfile('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py', wdir='C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx')

File "C:\Users\Karl Kraft\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\Users\Karl Kraft\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 46, in <module>
main()

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 39, in main
locations = read_locations(url="https://torstatus.blutmagie.de/")

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 32, in read_locations
query = dict(parse_qsl(urlparse(anchor[0]).query))

File "C:\Users\Karl Kraft\Anaconda3\lib\urllib\parse.py", line 367, in urlparse
url, scheme, _coerce_result = _coerce_args(url, scheme)

File "C:\Users\Karl Kraft\Anaconda3\lib\urllib\parse.py", line 123, in _coerce_args
return _decode_args(args) + (_encode_result,)

File "C:\Users\Karl Kraft\Anaconda3\lib\urllib\parse.py", line 107, in _decode_args
return tuple(x.decode(encoding, errors) if x else '' for x in args)

File "C:\Users\Karl Kraft\Anaconda3\lib\urllib\parse.py", line 107, in <genexpr>
return tuple(x.decode(encoding, errors) if x else '' for x in args)

File "C:\Users\Karl Kraft\Anaconda3\lib\site-packages\bs4\element.py", line 1173, in decode
indent_space = (' ' * (indent_level - 1))

TypeError: unsupported operand type(s) for -: 'str' and 'int'

Grüße, S.

Re: String-Operation

Verfasst: Mittwoch 21. August 2019, 14:22
von Strawk
Hier noch der Traceback von: anchor['href']

runfile('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py', wdir='C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx')
Reloaded modules: geo_mk, geo_mk.geo_gpx, geo_mk.geo_distances, geo_mk.geo_utils, geo_mk.geo_visualization
Traceback (most recent call last):

File "<ipython-input-5-04c4a6166c3e>", line 1, in <module>
runfile('C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py', wdir='C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx')

File "C:\Users\Karl Kraft\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 705, in runfile
execfile(filename, namespace)

File "C:\Users\Karl Kraft\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 46, in <module>
main()

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 39, in main
locations = read_locations(url="https://torstatus.blutmagie.de/")

File "C:/Users/Karl Kraft/Documents/Programmierung_ausser_PHP/Python/gpx/TorSiteCompleteInfo.py", line 32, in read_locations
query = dict(parse_qsl(urlparse(anchor['href']).query))

TypeError: list indices must be integers or slices, not str

Gruß, Strawk

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 11:24
von Strawk
Hallo!
Ich bin jetzt wieder bei den regulären Ausdrücken. Anders lassen sich nicht alle Informationen aus der Tabelle scrapen.
Bitte betrachtet folgenden String:

Code: Alles auswählen

<tr class='r'>
<td class='TRr'>
<a href='http://www.openstreetmap.org/?mlon=9.4910&mlat=51.2993&zoom=6' target='_blank'><img src='img/flags/de.gif' class='flag' width='18px' title='//DE' alt='DE' border='0'></a>
&nbsp;
<a href='router_detail.php?FP=749ef4a434dfd00dab31e93de86233fb916d31e3' target='_blank'>ExitNinja</a></td>
<td class='TDb'>
<table cellspacing='0' cellpadding='0' class='bwb'>
<tr title='57259 KBs'><td class='bwr5'><img src='img/bar/9.png' width='12px' height='15px' alt='57259'></td><td>&nbsp;<small>&nbsp;57259</small></td></tr>
</table>
</td>

<td class='TDcb'>33 d</td>
<td class='TDS'>
<table class='iT'>
<tr><td class='iT'>46.165.245.154 [<a class='who' href='/cgi-bin/whois.pl?ip=46.165.245.154' target='_blank'>46.165.245.154</a>]</td>
<td><img src='img/status/Fast.png' title='Fast Server' alt='Fast Server'></td>
<td><img src='img/status/Exit.png' title='Exit Server' alt='Exit Server'></td>
<td><img src='img/status/Dir.png' title='Directory Server' alt='Directory Server'></td>
<td><img src='img/status/Guard.png' title='Guard Server' alt='Guard Server'></td>
<td><img src='img/status/Stable.png' title='Stable Server' alt='Stable Server'></td>
<td><img src='img/os-icons/Linux.png' title='Tor 0.4.0.5 on Linux' alt='Tor 0.4.0.5 on Linux'></td>
</tr>
</table>
</td>
<td class='TDc'><b>443</b></td>
<td class='TDc'><b>80</b></td>
<td class='F0'></td>
<td class='TDS'>2014-11-06&nbsp;</td>
<td class='TDS'>LEASEWEB-DE-FRA-10, DE&nbsp;</td>
<td class='TDS'>28753&nbsp;</td>
<td class='TDc'>120000&nbsp;</td>
<td class='TDS'>&nbsp;</td>
</tr>
Ich bastele gerade an einem regulären Ausdruck, der mir den Routernamen liefert (hier: ExitNinja). Wie muss der wohl lauten?
Grüße
Strawk

P.S.: So jedenfalls nicht:

Code: Alles auswählen

result_rounter_name = re.search(r"target[=]*'[_]*blank'&gt;[a-zA-Z0-9]{3,30}&lt;[/]*a&gt;&lt;[/]*td&gt;", table_row)

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 11:42
von __blackjack__
@Strawk: Reguläre Ausdrücke sind nicht geeignet HTML zu parsen. Und natürlich geht das auch ohne regulären Ausdruck und zwar *einfach*, denn das ist ja einfach der Textinhalt vom zweiten <a> in der Tabellenzelle. Da kommt man mit Beautifulsoup wesentlich einfacher und verständlicher heran als der Ausdruck den Du da jetzt schon verbrochen hast.

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 12:18
von Sirius3
@Strawk: ich will Dir hier nicht jeden simplen Fehler, den man schnell durch Debugging beheben könnte, lösen. Wenn man nicht weiß, warum z.B. ein Index nicht richtig ist, dann gibt man einfach vor der Stelle die betroffenen Variablen aus und sieht ganz schnell dass find_all natürlich eine Liste von HTML-Objekten zurückliefert, man also (da an der Stelle wohl nur eines möglich ist) auf das 0te-Element zugreifen muß, um dann EIN HTML-Objekt zu haben, von dem man dann das href-Attribut abfragen kann.

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 14:21
von Strawk
@Sirius3: Dass anchor[0] nicht funktioniert, so weit waren wir schon. Es ist nunmal des einen Spaziergang des anderen Gewaltmarsch und ich bitte um Übermittlung des funktionierenden Klarcodes! Danke. Grüße, S. (Seit Wochen am Basteln, da kann einem doch mal kurzfristig auf die Sprünge geholfen werden; es ist ja nicht so, dass ich mir keine Mühe gäbe oder das Programmieren-Lernen mit lieferando verwechselte.)

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 14:33
von Sirius3
Du solltest den Code auseinandernehmen und debuggen, wie man das nun macht, wenn ein Programm nicht funktioniert.

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 15:31
von snafu
Also den Routernamen kann man so ermitteln:

Code: Alles auswählen

from bs4 import BeautifulSoup
from io import StringIO
import re

TEST_STREAM = StringIO("""\
<tr class='r'>
<td class='TRr'>
<a href='http://www.openstreetmap.org/?mlon=9.4910&mlat=51.2993&zoom=6' target='_blank'><img src='img/flags/de.gif' class='flag' width='18px' title='//DE' alt='DE' border='0'></a>
&nbsp;
<a href='router_detail.php?FP=749ef4a434dfd00dab31e93de86233fb916d31e3' target='_blank'>ExitNinja</a></td>
<td class='TDb'>
<table cellspacing='0' cellpadding='0' class='bwb'>
<tr title='57259 KBs'><td class='bwr5'><img src='img/bar/9.png' width='12px' height='15px' alt='57259'></td><td>&nbsp;<small>&nbsp;57259</small></td></tr>
</table>
</td>

<td class='TDcb'>33 d</td>
<td class='TDS'>
<table class='iT'>
<tr><td class='iT'>46.165.245.154 [<a class='who' href='/cgi-bin/whois.pl?ip=46.165.245.154' target='_blank'>46.165.245.154</a>]</td>
<td><img src='img/status/Fast.png' title='Fast Server' alt='Fast Server'></td>
<td><img src='img/status/Exit.png' title='Exit Server' alt='Exit Server'></td>
<td><img src='img/status/Dir.png' title='Directory Server' alt='Directory Server'></td>
<td><img src='img/status/Guard.png' title='Guard Server' alt='Guard Server'></td>
<td><img src='img/status/Stable.png' title='Stable Server' alt='Stable Server'></td>
<td><img src='img/os-icons/Linux.png' title='Tor 0.4.0.5 on Linux' alt='Tor 0.4.0.5 on Linux'></td>
</tr>
</table>
</td>
<td class='TDc'><b>443</b></td>
<td class='TDc'><b>80</b></td>
<td class='F0'></td>
<td class='TDS'>2014-11-06&nbsp;</td>
<td class='TDS'>LEASEWEB-DE-FRA-10, DE&nbsp;</td>
<td class='TDS'>28753&nbsp;</td>
<td class='TDc'>120000&nbsp;</td>
<td class='TDS'>&nbsp;</td>
</tr>""")

def get_router_name(soup):
    pattern = re.compile(r'router_detail.*')
    match = soup.find('a', href=pattern)
    if not match:
        raise ValueError('Missing router_detail link')
    return match.text

def main():
    soup = BeautifulSoup(TEST_STREAM)
    print(get_router_name(soup))

if __name__ == '__main__':
    main()
Anstelle von TEST_STREAM muss man natürlich den Stream von urlopen() oder requests einsetzen.

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 15:44
von __blackjack__
@snafu: Kann man natürlich so machen, aber das ist eine Tabelle in der die Zeilen immer so aufgebaut sind, dass in der ersten Zelle erst ein Link zu OpenStreetMap ist (wo die latitude/longitude-Informationen drin stecken die vorher hier Thema waren), und dann der Routername.

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 15:54
von snafu
Strawk hat geschrieben: Donnerstag 22. August 2019, 14:21 Es ist nunmal des einen Spaziergang des anderen Gewaltmarsch
Allerdings. Ich hatte halt noch in Erinnerung, dass BeautifulSoup reguläre Ausdrücke beherrscht, aber ich wusste nicht mehr genau, wie man vorgehen muss. Also Google angeschmissen und nach "beautifulsoup href regex" gesucht und dann war der Rest schnell runtergetippt und funktionierte auch gleich beim ersten Durchlauf.

Neben einer gewissen Erfahrung, logischem Denken und dem ganzen anderen "Programmier-Kram" gehört zu einer erfolgreichen Lösung eben auch einfach die Fähigkeit, eine Suchmaschine vernünftig zu bedienen. Dann stößt man meist auf Doku oder auf Beispiele von StackOverflow. Gerade so triviale Sachen kosten einen dann vielleicht 5 Minuten Lebenszeit...

Re: String-Operation

Verfasst: Donnerstag 22. August 2019, 15:56
von snafu
@__blackjack__: Ich hab hier ehrlich gesagt nur die letzten Beiträge gelesen. Wenn man sich auf eine fixe Position verlassen kann, dann ginge natürlich auch ein entsprechender Indexzugriff.

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 09:07
von Strawk
Hallo Nutzer!
Nach Refaktorierung des Skripts braucht es nun 115 Sekunden, anstatt 42. Ich habe versucht, mit einem zeilenweise Profiler zu arbeiten. Der Befehl
python -m line_profiler scrapeTor.py.lprof > results.txt
generiert auch tatsächlich das Skript results.txt. Dessen einziger Eintrag ist jedoch
Timer unit: 3.20721e-07 s
.
Warum fehlen die Zeitinfos?
Grüße
Strawk

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 09:21
von __blackjack__
@Strawk: Vielleicht weil das nix ausgeführt wird weil ``scrapeTor.py.lprof`` sehr wahrscheinlich nicht der Name des Programms ist‽

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 09:31
von Strawk
Doch. So lautet der Befehl. Erst:
kernprof -l scrapeTor.py
dann:
python -m line_profiler scrapeTor.py.lprof > results.txt
Mein Skript heißt scrapeTor.py

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 09:36
von Sirius3
Hast Du die Funktion, die Du profilieren willst, auch markiert?

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 09:56
von Strawk
Ich habe nichts markiert. Ich möchte das gesamte Skript auf seine Zeiten hin überprüfen.

Re: String-Operation

Verfasst: Mittwoch 28. August 2019, 10:33
von Sirius3
@Strawk: es hilft immer, die Dokumentation zu lesen, bevor man etwas benutzt:
It has been written to be used as a decorator, so in your script, you decorate the functions you want to profile with @profile.

Code: Alles auswählen

@profile
def slow_function(a, b, c):