2016-06-26 2 views
1

У меня вопрос о чтении HTML-файла из файлов данных и анализе данных, извлечении чисел и вычислении суммы чисел в файле.Скребковые номера из HTML с помощью BeautifulSoup

Вот код

from BeautifulSoup import * 
    import socket 

    mysock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
    mysock.connect(('python-data.dr-chuck.net',80)) 

    mysock.send('GET http://python-data.dr-chuck.net/comments_42.html HTTP/1.0\n\n') 
    while True: 
     data = mysock.recv(512000) 
     if (len(data) < 1) : 
      break 
     print data 
    mysock.close() 
    data2=BeautifulSoup(data) 

    tags=data2('a') 
    sum=0 
    for line in tags: 
     a=line.get('span',None) 
     sum+=int(a.text) 
    print sum 

Но я получаю следующее сообщение об ошибке

C:\Users\Dhruv>miscbeautifulsoup.py 
HTTP/1.1 400 Bad Request 
Date: Sun, 26 Jun 2016 05:14:31 GMT 
Content-Type: text/html 
Content-Length: 177 
Connection: close 
Server: -nginx 
CF-RAY: - 

<html> 
<head><title>400 Bad Request</title></head> 
<body bgcolor="white"> 
<center><h1>400 Bad Request</h1></center> 
<hr><center>cloudflare-nginx</center> 
</body> 
</html> 

Я не понимаю, почему я получаю сообщение об ошибке, и, хотя я использовал HTTP 1.0 ошибочное это упомянутый HTTP 1.1 , пожалуйста, помогите мне понять код ошибки.

+1

Есть ли причина, по которой вы используете сокеты вместо [urllib] (https://docs.python.org/2/library/urllib2.html) или [запросы] (https: //pypi.python. орг/PyPI/запросы)? –

ответ

1

Попробуйте изменить эту строку

mysock.send('GET http://python-data.dr-chuck.net/comments_42.html HTTP/1.0\n\n') 

в

mysock.send('GET /comments_42.html HTTP/1.0\n\n') 

Я посмотрел на запрос с этой страницы и в запросе источника страницы было предложено, как это.

GET /quant.js HTTP/1.1 
-1

Это суммировать все цифры под комментарии колонке:

import requests 
from bs4 import BeautifulSoup 
import re 

link = "http://python-data.dr-chuck.net/comments_42.html" 

reuest = requests.get(link) 
soup = BeautifulSoup(reuest.text,"lxml") 

soupl=soup.findAll("span", { "class" : "comments" }) 
sum=0 

for item in soupl: 
    sum = sum + int(item.text) 

print(sum) 
1

Вам нужно отправить некоторые заголовки, когда вы получаете /comments_42.html убедившись установить принять на utf-8/ascii так что вы получите текст обратно:

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
mysock.connect(('python-data.dr-chuck.net', 80)) 
mysock.send('''GET /comments_42.html HTTP/1.1 
Accept-Encoding:utf-8 
Host:python-data.dr-chuck.net 
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36.0\r\n\r\n 
''') 

Accept-Encoding:utf-8 и Host:python-data.dr-chuck.net необходимы для запроса на работу, ua является необязательным, но обычно это хорошая идея.

Полный рабочий код, используя bs4:

from bs4 import BeautifulSoup 
import socket 

mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
mysock.connect(('python-data.dr-chuck.net', 80)) 
mysock.send('''GET /comments_42.html HTTP/1.1 
Accept-Encoding:utf-8 
Host:python-data.dr-chuck.net\r\n\r\n 
''') 
html = "" 
while True: 
    data = mysock.recv(1000) 
    html += data 
    if data.endswith("\r\n\r\n"): 
     break 

mysock.close() 
data2 = BeautifulSoup(html) 
sm = sum(int(s.text) for s in data2.select("span.comments")) 
print(sm) 

Что дает вам:

2553 

Заголовки ответа и тело находятся в HTML, я оставлю его себе, чтобы выяснить, разделяя их.

Смежные вопросы