Seite 3 von 3
Re: String-Operation
Verfasst: Mittwoch 28. August 2019, 10:47
von __blackjack__
@Strawk: Dann musst Du das wohl im Skript deutlich machen. Der Hilfetext zu ``-b``/``--builtin`` von ``kernprof`` listet die verschiedenen Möglichkeiten ja auf. Neben dem Dekorator könntest Du zum Beispiel am Anfang auch ein ``profile.enable()`` einbauen.
Edit: Vielleicht sogar per ``-s``/``--setup`` ausserhalb des Quelltextes.
Re: String-Operation
Verfasst: Mittwoch 28. August 2019, 13:29
von Strawk
Hallo!
Einer der Flaschenhälse scheint dieser Befehl zu sein:
Code: Alles auswählen
dataframe = pd.DataFrame(res, columns=["Router Name",
"Bandwidth (KB/s)",
"Uptime (days)",
"Longitude",
"Latitude",
"Hostname",
"IP",
"Exit Server",
"Directory Server",
"Fast Server",
"Guard Server",
"Stable Server",
"Tor Version",
"Tor Operating System",
"ORPort",
"DirPort",
"First Seen",
"ASName"
])
Er verbrät 35,5 % der Zeit. Frage mich wieso und wie ich das ändere.
Konnte die Zeit halbieren: Der Befehl war in der Schleife; da gehört er nicht hin!
Re: String-Operation
Verfasst: Mittwoch 28. August 2019, 14:52
von Sirius3
@Strawk: da niemand außer Dir Deinen Code kennt, ist es schwierig, zu sagen, warum das die meiste Zeit verbrät.
Re: String-Operation
Verfasst: Samstag 31. August 2019, 09:47
von Strawk
Hallo!
Ich möchte aus einem Dataframe eine Liste ziehen, enthaltend die zweite und die dritte Spalte des Dataframes und unter Droppen der Zeilen ohne Werte (None, NaN).
Grüße M.
Hier meine bisherigen Versuche ( 1,5 h):
Code: Alles auswählen
# tor_df_lon_lat = tor_df.dropna(subset=['mlon'], ['mlat'])
# tor_df_lon_lat = tor_df["mlon", "mlat"].notnull()
# tor_df_lon_lat = tor_df.notnull(["mlon", "mlat"])
# tor_df_lon_lat = tor_df["mlon", "mlat"].notnull()
# tor_df_lon_lat = tor_df.dropna(axis=0, subset=("mlon", "mlat"))
# tor_df_lon_lat = tor_df.dropna(axis=0, how='any', subset=('mlon', ))
# tor_df_lon_lat = tor_df.dropna(axis=0, how='any', subset=['mlon', 'mlat'])
# lon_lat_list = tor_df_lon_lat["mlon", "mlat"].tolist()
# print(tor_df_lon_lat)
# print(type(tor_df_lon_lat))
# print(lon_lat_list)
# print(len(lon_lat_list))
Re: String-Operation
Verfasst: Samstag 31. August 2019, 10:04
von Sirius3
Auch hier helfen wieder Beispiel-Inputdaten und gewünschtes Ergebnis.
Was z.B. funktioniert an ›dropna‹ nicht (wenn man davon absieht, dass man erstmal gültiges Python schreiben sollte)?
Re: String-Operation
Verfasst: Samstag 31. August 2019, 10:12
von ThomasL
Ich würde es so machen
Code: Alles auswählen
lon_lat_list = tor_df[["mlon", "mlat"]].dropna().values
Re: String-Operation
Verfasst: Montag 14. Oktober 2019, 13:56
von __blackjack__
Hier mal so ziemlich alles herausgezogen was dort in der Tabelle steht:
Code: Alles auswählen
#!/usr/bin/env python3
from datetime import datetime as DateTime
from functools import partial
from pathlib import Path
from urllib.parse import parse_qsl, urlparse
import bs4
import pandas
import requests
DURATION_UNIT_TO_DAY_FACTOR = {"d": 1, "h": 1 / 24}
def parse_string(name, node):
return {name: node.text.strip() or None}
def parse_int(name, node, na_value=""):
text = node.text.strip()
return {name: None if text == na_value else int(text)}
def parse_date(name, node):
return {name: DateTime.strptime(node.text.strip(), "%Y-%m-%d").date()}
def parse_router_name_cell(node):
country_link_node, router_name_link_node = node("a", recursive=False)
query_data = dict(parse_qsl(urlparse(country_link_node["href"]).query))
try:
longitude = float(query_data["mlon"])
latitude = float(query_data["mlat"])
except KeyError:
longitude = None
latitude = None
return {
"country": country_link_node.img["alt"] or None,
"longitude": longitude,
"latitude": latitude,
"router_name": router_name_link_node.text.strip() or None,
}
def parse_uptime_cell(node):
value, space, unit = node.text.strip().partition(" ")
if space != " ":
raise ValueError(f"expected space between value and unit in {node}")
return {"uptime": int(value) * DURATION_UNIT_TO_DAY_FACTOR[unit]}
def parse_flags_and_operating_system(node):
flag_names = ["authority", "directory", "exit", "fast", "guard", "stable"]
result = dict.fromkeys((f"is_{n}" for n in flag_names), False)
remaining_descriptions = list()
for image_description in (img["alt"] for img in node("img")):
if image_description.endswith(" Server"):
name, space, _ = image_description.partition(" ")
if space != " ":
raise ValueError(f"expected space in {image_description}")
name = f"is_{name.lower()}"
if name not in result:
raise ValueError(f"unknown flag {name}")
result[name] = True
else:
remaining_descriptions.append(image_description)
if len(remaining_descriptions) > 1:
raise ValueError(
f"expected just the tor software and operating system name in"
f" {remaining_descriptions}"
)
if remaining_descriptions:
tor_software, delimiter, operating_system = remaining_descriptions[
0
].rpartition(" on ")
if not delimiter:
raise ValueError(f"missing 'on' in {remaining_descriptions[0]}")
else:
tor_software = None
operating_system = None
result["tor_software"] = tor_software
result["operating_system"] = operating_system
return result
def parse_host_name_cell(node):
name_cell = node.find("td", "iT")
strings = name_cell.stripped_strings
result = {
"host_name": next(strings).split(None, 1)[0],
"ip": next(strings),
}
result.update(parse_flags_and_operating_system(node))
return result
def parse_bad_exit_cell(node):
classes = node["class"]
if "F0" in classes and "F1" in classes:
raise ValueError(f"ambigious css classes in bad exit cell: {classes}")
if "F0" in classes:
result = False
elif "F1" in classes:
result = True
else:
raise ValueError(f"unknown css classes for bad exit: {classes}")
return {"is_bad_exit": result}
def parse_row(node):
result = dict()
parsers = [
parse_router_name_cell,
partial(parse_int, "bandwith"),
parse_uptime_cell,
parse_host_name_cell,
partial(parse_int, "or_port"),
partial(parse_int, "dir_port", na_value="None"),
parse_bad_exit_cell,
partial(parse_date, "first_seen_on"),
partial(parse_string, "as_name"),
partial(parse_int, "as_number"),
partial(parse_int, "consensus_bandwidth"),
partial(parse_string, "or_address"),
]
for parse, cell_node in zip(parsers, node("td", recursive=False)):
result.update(parse(cell_node))
return result
def parse_page(soup):
return list(map(parse_row, soup.find("table", "displayTable")("tr", "r")))
def main():
# html_source = Path("Tor.htm").read_bytes()
response = requests.get("https://torstatus.blutmagie.de/")
response.raise_for_status()
html_source = response.text
soup = bs4.BeautifulSoup(html_source, "lxml")
exit_nodes = pandas.DataFrame(parse_page(soup))
print(exit_nodes)
print(exit_nodes.info())
print(exit_nodes.head())
if __name__ == "__main__":
main()