Извлечение исходного кода из файла html с помощью python3.1 urllib.request - PullRequest
1 голос
/ 05 января 2011

Я пытаюсь получить данные с помощью регулярных выражений из файла html, реализуя следующий код:

import urllib.request
def extract_words(wdict, urlname):
  uf = urllib.request.urlopen(urlname)
  text = uf.read()
  print (text)
  match = re.findall("<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text)

, который возвращает ошибку:

File "extract.py", line 33, in extract_words
match = re.findall("<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text)
File "/usr/lib/python3.1/re.py", line 192, in findall
return _compile(pattern, flags).findall(string)
TypeError: can't use a string pattern on a bytes-like object

После дальнейших экспериментовв IDLE я заметил, что uf.read () действительно возвращает исходный код html при первом его вызове.Но затем он возвращает a - b ''.Есть ли способ обойти это?

1 Ответ

2 голосов
/ 05 января 2011

uf.read () прочитает содержимое только один раз.Затем вы должны закрыть его и снова открыть, чтобы прочитать снова.Это верно для любого вида потока.Это, однако, не проблема.

Проблема в том, что чтение из любого двоичного источника, такого как файл или веб-страница, вернет данные в виде bytes, если вы не укажете кодировку.Но ваше регулярное выражение не указано как тип bytes, оно указано как Unicode str.

Модуль re вполне разумно откажется использовать шаблоны Unicode для байтовых данных, и наоборот,

Решение состоит в том, чтобы сделать шаблон регулярного выражения строкой байтов, что вы делаете, помещая ab перед ним.Отсюда:

match = re.findall(b"<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text)

Должно работать.Другой вариант - декодировать текст, чтобы он также представлял собой Unicode str:

encoding = uf.headers.getparam('charset')
text = text.decode(encoding)
match = re.findall("<tr>\s*<td>([\w\s.;'(),-/]+)</td>\s+<td>([\w\s.,;'()-/]+)</td>\s*</tr>", text)

(Кроме того, для извлечения данных из HTML я бы сказал, что lxml - лучший вариант).

...