staging.inyokaproject.org

URLs in HTML finden und in Datei speichern

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

Fisch133

Anmeldungsdatum:
20. Dezember 2021

Beiträge: Zähle...

Hallo zusammen,

ich muss HTML Websites nach bestimmten Links durchsuchen und diese dann in eine Textdatei speichern um diese zu späterem Zeitpunkt einem Downloadmanager zu übergeben.

In der HTML Datei sind die Links dann im Format

1
<a href="https://hoster.com/123456789" class="bbcode-link">...

wobei ich dann in der entstehenden Textdatei stehen haben will

https://hoster.com/123456789

Mit

1
egrep -o https://hoster.com/.* "page.html" >> "links.txt"

erhalte ich allerdings die komplette Zeile hinter dem hoster.com.

Wie kann ich den Befehl abändern, dass er wirklich nur die URL nimmt?

PS: hoster.com ist wichtig, da in der HTML noch viele andere Links sind, die aber nicht mit aufgenommen werden sollen.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Man kann HTML nicht sauber mit Tools parsen, die Zeilenbasiert arbeiten oder sich auf reguläre Ausdrücke verlassen. Ich würde einen richtigen HTML-Parser wie z.B. BeautifulSoup4 (Paket python3-bs4) nehmen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/usr/bin/env python3
import sys
from bs4 import BeautifulSoup

HOSTER = 'https://hoster.com/'

for arg in sys.argv[1:]:
    with open(arg) as f:
        soup = BeautifulSoup(f, 'html.parser')
        for link in soup.find_all('a'):
            if (url := link.get('href', '')).startswith(HOSTER):
                print(url)
./extract_links.py "page.html" >> "links.txt" 

Fisch133

(Themenstarter)

Anmeldungsdatum:
20. Dezember 2021

Beiträge: 6

Danke. Der Parser ist wohl genau das richtige für mein Problem. Leider bringt dein Beispiel ein Syntax Error bei mir

    if (url := link.get('href', '')).startswith(HOSTER):
            ^
SyntaxError: invalid syntax

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Welche Python-Version hast du?

python3 --version 

Python 3.8 (das bei Ubuntu 20.04 dabei ist) beherrscht den Assignment Expressions eigentlich schon: https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions

shiro Team-Icon

Supporter

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1303

Hallo Fisch133,

normalerweise macht man so eine Aufgabe mit einem xml fähigen Programm (z.B. xmllint --html), aber wenn du grep nutzen willst, solltest du beim Such-regex

statt:  egrep -o https://hoster.com/.* "page.html" >> "links.txt"
besser: grep -o "https://hoster.com/[^ >\"]*" page.html >> links.txt

machen. Aber dir ist sicher klar, dass damit auch der gesuchte String gefunden wird, der nicht in einem Anker (<a></a>) steht. Alternativ zu grep kann man auch sed oder awk nutzen. Sicherer ist die xmllint (oder ähnliches Programm) Variante.

Das ginge z.B. so:

echo "cat //*/@href" | xmllint --html --shell page.html | grep -oi "https://hoster.com[^ \"]*" >> links.txt

oder etwas kürzer

xmllint --html --xpath "//*/@href" page.html | grep -oi "https://hoster.com[^ \"]*" >> links.txt

oder etwas stringenter: alle <a>, bei denen ein "href=" existiert, dessen Inhalt mit "https://hoster.com" beginnt:

xmllint --html --xpath '//*/a[starts-with(@href,"https://hoster.com")]/@href' page.html | sed 's/.*href=//;s/"//g' >> links.txt
Antworten |