2017-02-26 4 views
0

Je souhaite extraire divers éléments de tables et de textes de paragraphes de ce site Web.Extraction d'éléments Web à partir de sites Web utilisant Python

https://www.instituteforsupplymanagement.org/about/MediaRoom/newsreleasedetail.cfm?ItemNumber=30655

Ce code J'utilise:

import lxml 
from lxml import html 
from lxml import etree 
import urllib2 
source = urllib2.urlopen('https://www.instituteforsupplymanagement.org/about/MediaRoom/newsreleasedetail.cfm?ItemNumber=30656&SSO=1').read() 
x = etree.HTML(source) 
growth = x.xpath("//*[@id="home_feature_container"]/div/div[2]/div/table[2]/tbody/tr[3]/td[2]/p)") 
growth 

Quelle est la meilleure façon d'extraire les éléments que je veux d'un site Web sans avoir à changer le XPath dans le code à chaque fois? Ils publient de nouvelles données sur le même site tous les mois, mais le XPath semble parfois changer un peu.

+0

Quels sont les éléments que vous voulez? votre XPath n'est pas valide et ne peut pas être testé sur cette page. –

+0

J'ai changé le xpath. J'ai besoin d'éléments de la table «Fabrication en un coup d'œil». Et aussi le texte du paragraphe. –

Répondre

1

Si la position des éléments que vous voulez change régulièrement, essayez de les récupérer par son nom. Voici, par exemple, comment extraire les éléments de la table dans la ligne "New Orders".

import requests #better than urllib 
from lxml import html, etree 

url = 'https://www.instituteforsupplymanagement.org/about/MediaRoom/newsreleasedetail.cfm?ItemNumber=30655&SSO=1' 
page = requests.get(url) 
tree = html.fromstring(page.content) 

neworders = tree.xpath('//strong[text()="New Orders"]/../../following-sibling::td/p/text()') 

print(neworders) 

Ou si vous voulez l'ensemble table html:

data = tree.xpath('//th[text()="MANUFACTURING AT A GLANCE"]/../..') 

for elements in data: 
    print(etree.tostring(elements, pretty_print=True)) 

Un autre exemple en utilisant BeautifulSoup

from bs4 import BeautifulSoup 
import requests 

url = "https://www.instituteforsupplymanagement.org/about/MediaRoom/newsreleasedetail.cfm?ItemNumber=30655&SSO=1" 

content = requests.get(url).content 

soup = BeautifulSoup(content, "lxml") 

table = soup.find_all('table')[1] 

table_body = table.find('tbody') 

data= [] 
rows = table_body.find_all('tr') 
for row in rows: 
    cols = row.find_all('td') 
    cols = [ele.text.strip() for ele in cols] 
    data.append([ele for ele in cols if ele]) 

print(data) 
+0

Hey Ettore, il y avait un petit problème. J'ai décrit ici: http://stackoverflow.com/q/42592948/4399016 Merci! –

0

BeautifulSoup à la rescousse:

from bs4 import BeautifulSoup 
import urllib2 

r = urllib2.urlopen('https://www.instituteforsupplymanagement.org/about/MediaRoom/newsreleasedetail.cfm?ItemNumber=30655') 
soup = BeautifulSoup(r) 
soup.find('div', {'id': 'home_feature_container'}, 'h4') 

Ce code est en voie de remplir les spécifications comme décrit. Si vous utilisez soup.find().contents, il a créé une liste de chaque élément contenu dans l'élément.

En ce qui concerne les modifications sur la page, cela dépend vraiment. Si les changements sont dramatiques, vous devrez changer soup.find(). Sinon, vous pouvez écrire un code assez général pour qu'il s'applique toujours. (Comme si le div appelé home_feature_container est toujours sélectionnée, vous auriez jamais changer cela.)

+0

Salut, pourriez-vous montrer un exemple de code qui renvoie une valeur. Il y a une table «MANUFACTURING EN UN COUP D'ŒIL». Pourriez-vous montrer un élément extrait et affiché avec votre technique. Merci beaucoup!! –