J'essaie d'extraire des données d'un site Web. Cependant il me retourne incomplete read
. Les données que j'essaie d'obtenir sont un ensemble énorme de liens imbriqués. J'ai fait des recherches en ligne et j'ai constaté que cela était peut-être dû à une erreur de serveur (l'encodage d'un transfert en bloc se terminant avant Atteignant la taille attendue). J'ai également trouvé une solution de contournement pour ce qui précède link
Cependant, je ne suis pas sûr de savoir comment utiliser cela pour mon cas. Voici le code sur lequel je travaille
br = mechanize.Browser()
br.addheaders = [('User-agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1;Trident/5.0)')]
urls = "http://shop.o2.co.uk/mobile_phones/Pay_Monthly/smartphone/all_brands"
page = urllib2.urlopen(urls).read()
soup = BeautifulSoup(page)
links = soup.findAll('img',url=True)
for tag in links:
name = tag['alt']
tag['url'] = urlparse.urljoin(urls, tag['url'])
r = br.open(tag['url'])
page_child = br.response().read()
soup_child = BeautifulSoup(page_child)
contracts = [tag_c['value']for tag_c in soup_child.findAll('input', {"name": "tariff-duration"})]
data_usage = [tag_c['value']for tag_c in soup_child.findAll('input', {"name": "allowance"})]
print contracts
print data_usage
S'il vous plaît aidez-moi avec this.Merci
Le link que vous avez inclus dans votre question est simplement un wrapper qui exécute la fonction read () de urllib, qui intercepte toutes les exceptions de lecture incomplètes. Si vous ne souhaitez pas implémenter tout ce correctif, vous pouvez toujours insérer une boucle try/catch dans laquelle vous lisez vos liens. Par exemple:
try:
page = urllib2.urlopen(urls).read()
except httplib.IncompleteRead, e:
page = e.partial
pour python3
try:
page = request.urlopen(urls).read()
except (http.client.IncompleteRead) as e:
page = e.partial
Je découvre dans mon cas: envoyer une requête HTTP/1.0, en ajoutant ceci, corrige le problème.
import httplib
httplib.HTTPConnection._http_vsn = 10
httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0'
après avoir fait la demande:
req = urllib2.Request(url, post, headers)
filedescriptor = urllib2.urlopen(req)
img = filedescriptor.read()
après mon retour à http 1.1 avec (pour les connexions prenant en charge la version 1.1):
httplib.HTTPConnection._http_vsn = 11
httplib.HTTPConnection._http_vsn_str = 'HTTP/1.1'
l'astuce consiste à utiliser http 1.0 à la place de la valeur par défaut http/1.1 http 1.1 pourrait gérer des blocs mais, pour une raison quelconque, le serveur Web ne le fait pas. Nous effectuons donc la requête dans http 1.0.
Vous pouvez utiliser requests
au lieu de urllib2
. requests
est basé sur urllib3
, de sorte qu'il a rarement un problème. Mettez-le en boucle pour l'essayer 3 fois, et ce sera beaucoup plus fort. Vous pouvez l'utiliser de cette façon:
import requests
msg = None
for i in [1,2,3]:
try:
r = requests.get(self.crawling, timeout=30)
msg = r.text
if msg: break
except Exception as e:
sys.stderr.write('Got error when requesting URL "' + self.crawling + '": ' + str(e) + '\n')
if i == 3 :
sys.stderr.write('{0.filename}@{0.lineno}: Failed requesting from URL "{1}" ==> {2}\n'. format(inspect.getframeinfo(inspect.currentframe()), self.crawling, e))
raise e
time.sleep(10*(i-1))
Ce qui a fonctionné pour moi est de capturer IncompleteRead comme exception et de récolter les données que vous avez réussi à lire à chaque itération en les mettant dans une boucle comme ci-dessous: )
try:
requestObj = urllib.request.urlopen(url, data)
responseJSON=""
while True:
try:
responseJSONpart = requestObj.read()
except http.client.IncompleteRead as icread:
responseJSON = responseJSON + icread.partial.decode('utf-8')
continue
else:
responseJSON = responseJSON + responseJSONpart.decode('utf-8')
break
return json.loads(responseJSON)
except Exception as RESTex:
print("Exception occurred making REST call: " + RESTex.__str__())
J'ai essayé toutes ces solutions et aucune d'entre elles n'a fonctionné pour moi. En fait, ce qui a fonctionné est au lieu d'utiliser urllib, je viens d'utiliser http.client (Python 3)
conn = http.client.HTTPConnection('www.google.com')
conn.request('GET', '/')
r1 = conn.getresponse()
page = r1.read().decode('utf-8')
Cela fonctionne parfaitement à chaque fois, alors qu’urllib renvoyait à chaque fois une exception incomplète.
Je viens d'ajouter une exception pour passer ce problème.
juste comme
try:
r = requests.get(url, timeout=timeout)
except (requests.exceptions.ChunkedEncodingError, requests.ConnectionError) as e:
logging.error("There is a error: %s" % e)
J'ai constaté que mon détecteur de virus/pare-feu était à l'origine de ce problème. "Bouclier en ligne" fait partie d'AVG.