2016-06-22 1 views
1

Je travaille à extraire un tableau spécifique d'un couple de documents, qui détient les signatures des administrateurs, pour un couple de sociétés utilisant BeautifulSoup4. Mon programme trouve un en-tête au-dessus de la section qui contient les tables, puis compte deux tables à partir de cet endroit pour trouver la bonne table (Les documents étant des documents gouvernementaux signifie que le format est vrai dans presque tous les cas). À l'heure actuelle, voici comment je le fais:Belle grattage de table de soupe ne racle qu'une partie du temps

soup=BeautifulSoup(theDocument) 

try: 
    tables = soup.find(text=re.compile("Pursuant to the requirements of Section 13")).findNext('table').findNext('table').strings 
except AttributeError as e: 
    #deal with error, output failed URL to file 

Avec ce code, je trouve les tables pour environ 70% de mes recherches, mais il suffit de jeter un peu l'erreur. Par exemple, this document est l'un de ceux qui ne trouve pas la table (vous pouvez trouver la section dans le document en faisant un CTRL + F pour la chaîne re.compile), mais this document de la même entreprise et ce qui ressemble à la même La mise en forme HTML donne des résultats positifs.

Des idées?

EDIT: le & nbsp peut être un problème, mais il y en a un autre aussi. Raccourcir la chaîne de recherche pour ne pas inclure le & nbsp entraîne toujours un échec.

EDIT2: Il semble qu'il y ait une erreur sous-jacente qui se produit parfois. J'ai essayé imprimer le code HTML de la variable de données et obtenu les éléments suivants:

<HTML><HEAD> 
<TITLE>Access Denied</TITLE> 
</HEAD><BODY> 
<H1>Access Denied</H1> 

You don't have permission to access "http&#58;&#47;&#47;www&#46;sec&#46;gov&#47;Archives&#47;edgar&#47;data&#47;1800&#47;000110465907013496&#47;a07&#45;1583&#95;110k&#46;htm" on this server.<P> 
Reference&#32;&#35;18&#46;ee9a1645&#46;1466687980&#46;5cc0b4f 
</BODY> 
</HTML> 

Toute façon de contourner ce problème, tout en retirant toujours le & nbsp?

EDIT 2: La réponse ci-dessous a résolu le problème que j'avais, donc je l'ai marqué comme réponse. Cela dit, il y avait un autre problème sous-jacent de newlines aléatoires dans la chaîne, donc j'ai modifié mon regex pour vérifier '\ s +' entre tous les mots au lieu de seulement des espaces. VEILLEZ A VERIFIER LE CODE HTML POUR CETTE ERREUR SI VOUS TROUVEZ UN PROBLEME COMME CELA.

+2

Avez-vous essayez d'utiliser un analyseur différent? Par exemple: 'BeautifulSoup (theDocument, 'html.parser')' – Jkdc

+0

@Jkdc D'après l'une des réponses, j'ai essayé d'utiliser lxml en tant qu'analyseur secondaire. Cela a causé plus d'erreurs que cela a résolu :) Cela étant dit, il PEUT travailler pour ramasser les cas que la première tentative n'attrape pas. – Retroflux

+0

@Jkdc Le problème s'est développé si vous souhaitez vous faire une idée. – Retroflux

Répondre

2

Le problème est le &nbsp; entre le Section et 13:

<font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pursuant to the requirements of Section&nbsp;13 or 15(d) of the Securities Exchange Act of 1934, Abbott Laboratories has duly caused 
this report to be signed on its behalf by the undersigned, thereunto duly authorized. </font> 

Je voudrais utiliser un searching function et replace the &nbsp; with a regular space lors de la vérification de la .text propriété:

import requests 
from bs4 import BeautifulSoup 


# url = "https://www.sec.gov/Archives/edgar/data/1800/000110465907013496/a07-1583_110k.htm" 
url = "https://www.sec.gov/Archives/edgar/data/1800/000104746916010246/a2227279z10-k.htm" 
response = requests.get(url, headers={ 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" 
}) 

data = response.text 
soup = BeautifulSoup(data, "lxml") 

text_to_search = "Pursuant to the requirements of Section 13" 
p = soup.find(lambda elm: elm.name == "p" and elm.text and text_to_search in elm.text.replace(u'\xa0', ' ')) 
tables = p.findNext('table').findNext('table').strings 
+0

Hey, merci pour le correctif. Il a résolu certaines des erreurs mais a engendré un grand nombre de nouvelles. Je vais certainement essayer d'incorporer certaines de vos idées dans mon code, peut-être en tant que système de la troisième chance. Pourriez-vous expliquer comment fonctionne la ligne soup.find? Je n'ai pas vu certains de ces éléments auparavant. – Retroflux

+0

@Retroflux bien, semble avoir résolu ce problème particulier que vous avez demandé, n'hésitez pas à poser une question distincte (s) si besoin d'aide supplémentaire avec le code. L'astuce que j'utilise dans la réponse est fondamentalement une fonction qui aide à faire une certaine opération (remplacer dans ce cas) sur un texte avant de vérifier s'il y a une sous-chaîne désirée. 'BeautifulSoup' est assez flexible dans la localisation des éléments et fournit toutes sortes de façons de le faire. J'espère que cela pourra aider. – alecxe

+0

Après beaucoup de tests, j'ai remarqué qu'il échouait à ce test même si je ne faisais que rechercher le mot "Section", qui n'inclurait pas le caractère & nbsp. Pourrait-il y avoir une autre raison pour laquelle cela échoue? – Retroflux