Я вчера написал об этом вопросе, но все предложили мне использовать библиотеку BeautifulSoup. Мне не разрешают использовать какие-либо внешние библиотеки для класса, но я продвинулся немного дальше. Код должен открывать данный веб-сайт и добавлять любую информацию между тегами заголовка. Это вводный класс, так что я понимаю, что могу спросить кое-что довольно простое. Как я могу исправить любые синтаксические ошибки? Особая проблема заключается в объявлении моей переменной "findHeader".
Редактировать: Traceback (последний вызов был последним): Файл "C: \ Users \ Cameron \ Desktop \ заголовок сайта search.py", строка 16, в if (findHeader, headerEnd) в строке: TypeError: 'in' требуется строка слева операнд, а не кортеж
from urllib.request import urlopen
address = "http://www.hobo-web.co.uk/headers/"
webPage = urlopen (address)
list = []
encoding = "utf-8"
for line in webPage:
line = str(line, encoding)
findHeader = ('h1', 'h2', 'h3', 'h4', 'h5', 'h6')
headerEnd = ('/h1', '/h2', '/h3', '/h4', '/h5', '/h6')
if (findHeader, headerEnd) in line:
start = line.index(findHeader, headerEnd) + len(findHeader, headerEnd)
last = line.index('"', start)
list.append(line[start : last])
webPage.close()
4 ответа
Вот еще одно очень простое решение проблемы. Я считаю, что вы хотите найти подходящие заголовки (например, <h1>
и </h1>
в одной строке). Это очень простое решение, которое не использует какую-либо внешнюю библиотеку:
findHeader = ('<h1>', '<h2>', '<h3>', '<h4>', '<h5>', '<h6>')
line = 'This is the <h1>header content</h1> and this is not'
for startHeader in findHeader:
endHeader = '</'+startHeader[1:]
if (startHeader in line) and (endHeader in line):
content = line.split(startHeader)[1].split(endHeader)[0]
print content
Распечатывает:
header content
Чтобы вставить это в свой код:
from urllib.request import urlopen
address = "http://www.w3schools.com/html/html_head.asp"
webPage = urlopen (address)
encoding = "utf-8"
for line in webPage:
findHeader = ('<h1>', '<h2>', '<h3>', '<h4>', '<h5>', '<h6>')
line = str(line, encoding)
for startHeader in findHeader:
endHeader = '</'+startHeader[1:]
if (startHeader in line) and (endHeader in line):
content = line.split(startHeader)[1].split(endHeader)[0]
print (content)
webPage.close()
if (findHeader, headerEnd) in line:
Как говорит трассировка, вы не можете проверить, находится ли кортеж в строке. Я предполагаю, что вы пытаетесь проверить, находятся ли они в очереди. Это работа для any
.
if any(header in line for header in (findHeader, headerEnd)):
do_things
Как ваше сообщение об ошибке говорит:
Ошибка типа: для 'in' в качестве левого операнда требуется строка, а не кортеж
Когда вы говорите « ищите что-то в этой строке, », вы ожидаете, что вы ищете строку в этой строке. Если вы хотите проверить, содержит ли строка (line
) хотя бы один из нескольких возможных вариантов (findHeader
и / или headerEnd
), вам следует выполнить некоторые действия. вид итерации, проверяющий каждую опцию, чтобы увидеть, присутствует ли она.
Существует множество способов справиться с подобной итерацией / проверкой в Python. Некоторые из них являются однострочными решениями, а некоторые занимают несколько строк. На мой взгляд, наиболее читаемый способ - написать цикл, который будет перебирать список возможностей (findHeader
) и проверять наличие значений. Если присутствует одно из значений, выйдите из цикла и проверьте, присутствует ли соответствующий закрывающий тег (headerEnd
).
Ниже приведен пересмотр вашего кода для выполнения такой проверки очень читабельным способом:
for line in webPage.split("\n"):
line = str(line, encoding)
findHeader = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
headerEnd = ['/h1', '/h2', '/h3', '/h4', '/h5', '/h6']
headerIndexNumber = -1
for i in range(len(findHeader)):
# Attempt to find the start of a header in the line
if(( '<' + findHeader[i]) in line):
# The line contains what appears to be the start of a header
headerIndexNumber = i
break
# End if
# End for
# Check if the for loop above found a header index
if(headerIndexNumber >= 0):
# Great, we found a header index number in the line above
# Now let's check for a respective closing tag.
if(('<' + headerEnd[headerIndexNumber]) in line):
# Cool, the line also appears to contain a closing tag for
# the same type of header.
## ... <YOUR CODE HERE FOR DOING SOMETHING EITHER BETWEEN
## ... OR WITH THE HTML HEADER TAGS> ...
# End if(header closing tag was found in line)
# End if(header start tag was found in line)
# End foreach loop (line in webPage)
Очевидно, это всего лишь пересмотренный кусок вашего кода. Если вы решите использовать это как свое решение, вам нужно будет поместить его в существующий код там, где это уместно, и вам все равно нужно будет написать внутреннюю логику (т. Е. Код, который обрабатывает то, что вы делаете однажды найден тег заголовка в строке).
Тем не менее, я попытался написать этот код очень читабельным и понятным способом с комментариями, которые объясняют, что делает каждая строка. Если какая-либо вещь в коде, который я включил выше, не имеет смысла, пожалуйста, оставьте комментарий, и я постараюсь объяснить это.
Несколько замечаний по предоставленному коду:
Я делаю
for line in webPage.split("\n")
. Я проверил это локально, установивwebPage
в строку, содержащую исходный HTML-код веб-страницы. Из-за этого источник веб-страницы нужно было разбить на отдельные строки, иначе цикл for просто будет проходить через каждый отдельный символ в HTML-коде веб-страницы, а не через полные строки. Если это не относится к вашему коду, просто удалите команду split.Когда я проверяю теги заголовка в строке, я добавляю
<
к искомому значению. Это потому, что HTML-теги всегда начинаются с<
. Так что это предотвратит ложно-положительное совпадение, если в строке только что написано «h1».
РЕДАКТИРОВАТЬ . Что касается вашего комментария, OP, ниже приведен простой способ распечатать строки между тегами h
на основе кода, который вы опубликовали в Pastebin:
from urllib.request import urlopen
address = "http://www.w3schools.com/html/html_head.asp"
webPage = urlopen (address)
encoding = "utf-8"
list = []
for line in webPage:
findHeader = ('<h1>', '<h2>', '<h3>', '<h4>', '<h5>', '<h6>')
line = str(line, encoding)
for startHeader in findHeader:
endHeader = '</'+startHeader[1:]
if (startHeader in line) and (endHeader in line):
content = line.split(startHeader)[1].split(endHeader)[0]
list.append(line)
for h in list:
print((h[4:]).strip()[:-5])
webPage.close()
Если ваш случай так прост, я предлагаю использовать простое регулярное выражение.
import re
line = 'I am a <h1>jedi</h1> and you are not'
regex = re.compile('<h[0-9]>(.*)</h[0-9]>')
match = regex.search(line)
if match:
print(match.group(1))
Он вернется
jedi
Просто для полноты, вы не можете найти кортеж в строке так же, как вы не можете найти список в строке. Если вам действительно нужно следовать этому подходу, вы должны проверить каждый элемент в списке на соответствие вашей строке.
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.