Веб-скрейпинг urlopen в python

Я пытаюсь получить данные с этого сайта: http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS

Кажется, что urlopen не получает html-код, и я не понимаю, почему. Это выглядит так:

html = urllib.request.urlopen("http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS")
print (html)

Мой код правильный, я получаю html-код других веб-страниц с тем же кодом, но, похоже, он не распознает этот адрес.

он печатает: б''

Может быть, другая библиотека больше подходит? Почему urlopen не возвращает html-код веб-страницы? помогите спасибо!


person Community    schedule 23.08.2011    source источник
comment
Поиск потоков по теме веб-соединений на SO дал бы вам много информации. Но в любом случае это не серьезная ошибка для нового пользователя. Поэтому я проголосовал за ВАС, а не за вопрос, чтобы приветствовать вас на ТАК.   -  person eyquem    schedule 23.08.2011


Ответы (2)


Лично я пишу:

# Python 2.7

import urllib

url = 'http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS'
sock = urllib.urlopen(url)
content = sock.read() 
sock.close()

print content

Et si tu parles français, .. bonjour sur stackoverflow.com!

обновление 1

На самом деле, сейчас я предпочитаю использовать следующий код, потому что он быстрее:

# Python 2.7

import httplib

conn = httplib.HTTPConnection(host='www.boursorama.com',timeout=30)

req = '/includes/cours/last_transactions.phtml?symbole=1xEURUS'

try:
    conn.request('GET',req)
except:
     print 'echec de connexion'

content = conn.getresponse().read()

print content

Замены httplib на http.client в этом коде должно быть достаточно, чтобы адаптировать его к Python 3.

.

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

        <td class="L20" width="33%" align="center">11:57:44</td>

        <td class="L20" width="33%" align="center">1.4486</td>

        <td class="L20" width="33%" align="center">0</td>

</tr>

                                        <tr>

        <td  width="33%" align="center">11:57:43</td>

        <td  width="33%" align="center">1.4486</td>

        <td  width="33%" align="center">0</td>

</tr>

обновление 2

Добавление следующего фрагмента к приведенному выше коду позволит вам извлечь данные, которые, как я полагаю, вам нужны:

for i,line in enumerate(content.splitlines(True)):
    print str(i)+' '+repr(line)

print '\n\n'


import re

regx = re.compile('\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">(\d\d:\d\d:\d\d)</td>\r\n'
                  '\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">([\d.]+)</td>\r\n'
                  '\t\t\t\t\t\t<td class="(?:gras )?L20" width="33%" align="center">(\d+)</td>\r\n')

print regx.findall(content)

результат (только конец)

.......................................
.......................................
.......................................
.......................................
98 'window.config.graphics = {};\n'
99 'window.config.accordions = {};\n'
100 '\n'
101 "window.addEvent('domready', function(){\n"
102 '});\n'
103 '</script>\n'
104 '<script type="text/javascript">\n'
105 '\t\t\t\tsas_tmstp = Math.round(Math.random()*10000000000);\n'
106 '\t\t\t\tsas_pageid = "177/(includes/cours/last_transactions)"; // Page : boursorama.com/smartad_test\n'
107 '\t\t\t\tvar sas_formatids = "8968";\n'
108 '\t\t\t\tsas_target = "symb=1xEURUS#"; // TargetingArray\n'
109 '\t\t\t\tdocument.write("<scr"+"ipt src=\\"http://ads.boursorama.com/call2/pubjall/" + sas_pageid + "/" + sas_formatids + "/" + sas_tmstp + "/" + escape(sas_target) + "?\\"></scr"+"ipt>");\t\t\t\t\n'
110 '\t\t\t</script><div id="_smart1"><script language="javascript">sas_script(1,8968);</script></div><script type="text/javascript">\r\n'
111 "\twindow.addEvent('domready', function(){\r\n"
112 'sas_move(1,8968);\t});\r\n'
113 '</script>\n'
114 '<script type="text/javascript">\n'
115 'var _gaq = _gaq || [];\n'
116 "_gaq.push(['_setAccount', 'UA-1623710-1']);\n"
117 "_gaq.push(['_setDomainName', 'www.boursorama.com']);\n"
118 "_gaq.push(['_setCustomVar', 1, 'segment', 'WEB-VISITOR']);\n"
119 "_gaq.push(['_setCustomVar', 4, 'version', '18']);\n"
120 "_gaq.push(['_trackPageLoadTime']);\n"
121 "_gaq.push(['_trackPageview']);\n"
122 '(function() {\n'
123 "var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n"
124 "ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n"
125 "var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n"
126 '})();\n'
127 '</script>\n'
128 '</body>\n'
129 '</html>'



[('12:25:36', '1.4478', '0'), ('12:25:33', '1.4478', '0'), ('12:25:31', '1.4478', '0'), ('12:25:30', '1.4478', '0'), ('12:25:30', '1.4478', '0'), ('12:25:29', '1.4478', '0')]

Надеюсь, вы не планируете «играть» в трейдинг на Форексе: это один из лучших способов быстро потерять деньги.

обновление 3

ИЗВИНИ ! Я забыл, что вы с Python 3. Поэтому я думаю, что вы должны определить регулярное выражение следующим образом:

regx = re.compile(b'\t\t\t\t\t......)

то есть с b перед строкой, иначе вы получите сообщение об ошибке, как в этот вопрос

person eyquem    schedule 23.08.2011
comment
Мерси, я смогу протестировать код только сегодня вечером. Вы уверены, что получаете с ним исходный код html? И да, я на питоне 3 ;-) - person ; 23.08.2011
comment
@Kingpin Да, я понимаю, я редко публикую коды, которые не тестировал. Но я использую Python 2.7. Затем я понял, что вы работаете с Python 3, видя print(html) со скобками, но я недостаточно пробовал Python 3, чтобы знать, что мой код не будет работать в Python 3. Извините. - person eyquem; 23.08.2011
comment
httplib не существует в Python 3, и я бы посоветовал не использовать регулярное выражение для чего-то, что вы должны обрабатывать с помощью синтаксического анализатора (BeautifulSoup и др.). - person Cassandra S.; 23.08.2011
comment
@ Роберт С. Мы знаем, мы знаем. Утомительно всегда иметь одну и ту же реакцию, когда кто-то использует регулярные выражения для извлечения данных из исходного кода HTML. Фрагмент работает, и я написал его за 2 минуты. Готовы ли вы помочь Kingpin изучить BeautifulSoup за 1 или 2 часа? Кстати, BS в 10 раз медленнее, чем чистое приложение с регулярными выражениями. - person eyquem; 23.08.2011
comment
@euquem Достаточно честно - я просто думаю, что ему следует сказать, что это не всегда хорошая идея. Использование библиотеки означает, что вам не нужно вручную кодировать регулярные выражения, что, в свою очередь, делает ваш код более надежным (и более читабельным), и вам не придется исправлять ошибку каждый раз, когда плохой HTML нарушает ваше регулярное выражение. Но я понимаю вашу точку зрения; иногда вы можете использовать регулярные выражения. - person Cassandra S.; 23.08.2011
comment
@Robert S. Я согласен: не всегда хороший способ. Но человеку лучше знать, почему и когда. По сути, это разбор stricto sensu, который невозможен с помощью регулярных выражений; но здесь он не хочет анализировать, он просто хочет проанализировать и найти определенную и ограниченную часть исходного кода. - Что касается частого исправления ошибок, это не тот случай, когда анализируется всегда одна и та же часть исходного кода, это то, во что я верю, может быть, я ошибаюсь? - Кстати, я особенно люблю регулярные выражения, поэтому для меня не проблема создать шаблон регулярного выражения. - person eyquem; 23.08.2011

Я проверил ваш URL-адрес с помощью http://code.google.com/p/httplib2/ и на терминале с помощью curl. Оба работают нормально:

URL = "http://www.boursorama.com/includes/cours/last_transactions.phtml?symbole=1xEURUS"
h = httplib2.Http()
resp, content = h.request(URL, "GET")
print(content)

Так что для меня либо есть ошибка в urllib.request, либо происходит действительно странное взаимодействие клиент-сервер.

person jazz    schedule 23.08.2011
comment
Это была опечатка. Мой реальный код включает, чтобы сделать его строкой. Это не работает. Мой вопрос - настоящий вопрос - person ; 23.08.2011
comment
@jazz, вероятно, это сервер, который отправляет сжатые данные, urllib немного ограничен. - person Cassandra S.; 23.08.2011
comment
@Robert: К сожалению, нет; ответ пуст, и в Python 2 он тоже работает нормально. Он должен быть специфичен для Python 3 и urllib.request. - person jazz; 23.08.2011
comment
@jazz, но Content-length - это 7787 на response = urllib.request.urlopen(url), что указывает на то, что что-то отправляется, кроме простых заголовков - просмотр его с помощью онлайн-инструментов показывает ту же длину содержимого, но также и фактический исходный код, подразумевая, что это не пустой ответ. Так что да, с urllib.request происходит что-то странное. - person Cassandra S.; 23.08.2011