Я изучаю Python 3.8 и пытаюсь извлечь определенную часть исходного HTML-документа.

HTML-код содержит две строки, которые начинаются с ключевого слова, за которым следует значение в двойных кавычках:

keyword: "http://www.somesite.com/sample.txt"

Мне нужно извлечь только значение в кавычках если оно следует за первым экземпляром ключевого слова, поэтому результат должен быть http://www.somesite.com/sample.txt.

В моем коде до сих пор я пытаюсь сделать это с помощью регулярного выражения, но оно ничего не соответствует:

import re

import bs4
import pyperclip
import requests


def get_value(url):

    res = requests.get(url)
    res.raise_for_status()

    regex = re.compile("file: \"(http[^\s\"]+\.txt)\"")
    soup = bs4.BeautifulSoup(res.text, 'html.parser')
    return regex.search(soup.text).group().replace('file: "', '').replace('"', '')

# Print the URL from the clipboard
print(pyperclip.paste())

# Call get_value to return the required value between double quotes after file:
my_value = get_value(pyperclip.paste())

# Copy the final value to the clipboard
pyperclip.copy(my_value)

При выполнении я получаю следующую ошибку Python: AttributeError: 'NoneType' object has no attribute 'group'.

Я не очень знаком с регулярными выражениями, но также считаю, что есть лучший способ извлечь эти данные, поскольку собственный RegEx Wiki в Stack Overflow предлагает не использовать регулярное выражение в HTML.

0
Zephyr 8 Фев 2021 в 08:26

2 ответа

Лучший ответ

Ошибка, которую вы получаете, скорее всего, связана с тем, что совпадений не найдено в regex.search, и в этом случае он возвращает None, а вызов метода .group для None возвращает ошибку : AttributeError: 'NoneType' object has no attribute 'group'.

Не имея конкретного образца HTML, с которым вы работаете, трудно сказать, почему он не совпадает. Основываясь на примере в сообщении, это может быть связано с тем, что ваш шаблон регулярного выражения ищет строки, начинающиеся с file, а HTML содержит строки, начинающиеся с keyword.

Если есть совпадение в HTML, оно должно работать. Вот пример:

import bs4
import re

html = """
<html>
    <body>
        <p>file: "http://www.somesite.com/sample1.txt"</p>
        <p>file: "http://www.somesite.com/sample2.txt"</p>
        <p>file: "http://www.somesite.com/non-matching.jpg"</p>
    </body>
</html>
"""

regex = re.compile("file: \"(http[^\s\"]+\.txt)\"")
soup = bs4.BeautifulSoup(html, 'html.parser')
regex.search(soup.text).group(1)

Выход:

'http://www.somesite.com/sample1.txt'
3
perl 7 Мар 2021 в 16:47

Увидев часть строки, которую вы разделяете. Попробуйте использовать приведенное ниже регулярное выражение

regex = re.compile(r'file:.*\"(.*)\"')
soup = bs4.BeautifulSoup(res.text, 'html.parser')
return regex.match(soup.text).group(1)
0
Arpit 9 Мар 2021 в 06:58