2017-01-30 2 views
-4

Ich versuche, Geschichten aus nbcnews.com zu extrahieren. Im Moment habe ich den folgenden Code:Nachrichtenartikel in Python mit BeautifulSoup erhalten

import urllib2 
from bs4 import BeautifulSoup 

# The page that I'm getting stories from 
url = 'http://www.nbcnews.com/' 

data = urllib2.urlopen(url) 

soup = BeautifulSoup(data, 'html.parser') 

#This is the tag and class that chrome told me "top stories" are stored in 
this = soup.find_all('div', attrs={"class": "col-sm-6 col-md-8 col-lg-9"}) 

#Get the a tags in the previous tag (this is the part that returns FAR too many links 

link = [a for i in this for a in i.find_all('a')] 

#Get the titles (This works) 
title = [a.get_text() for i in link for a in i.find_all('h3')] 

#The below strips all newlines and tabs from the title name 
newtitle = [] 

for i in t: 
    s = ' '.join(i.split()) 
    if s in newtitle: 
     pass 

    else: 
     newtitle.append(s) 

print len(link) 
print len(title) 

Als ich das Skript ausführen, ist der „Titel“ -Liste (meist) korrekt mit leichten Variationen auf den Titelnamen vor Ort (Titelname ist kein Problem, wenn es in der Nähe zu der gleichen Sache)

Mein Problem ist, dass die "Link" -Liste Links von überall zu enthalten scheint? Kann mir jemand dabei helfen?

Oder, wenn möglich, gibt es eine API für etwas ähnliches? Ich möchte wirklich nicht das Rad neu erfinden, um Nachrichtenartikel zu bekommen, wenn ich es vermeiden kann.

EDIT: einen Tippfehler in einem Variablennamen

Antwort

1

Mit Blick auf die Webseite in Frage geändert, es sieht aus wie alle newstories sind in h3-Tags mit der Klasse item-heading. Sie können BeautifulSoup verwenden, um alles Story-Header auswählen und dann BeautifulSoup die .parent Methode nach oben in dem HTML-Baum zu treten und die a href zuzugreifen, dass sie innerhalb enthalten sind:

In [54]: [i.parent.attrs["href"] for i in soup.select('a > h3.item-heading')] 
Out[55]: 
[{'href': '/news/us-news/civil-rights-groups-fight-trump-s-refugee-ban-uncertainty-continues-n713811'}, 
{'href': '/news/us-news/protests-erupt-nationwide-second-day-over-trump-s-travel-ban-n713771'}, 
{'href': '/politics/politics-news/some-republicans-criticize-trump-s-immigration-order-n713826'}, 
... # trimmed for readability 
] 

ich eine Liste Verständnis verwendet habe, aber Sie spalten konnte in den Verbund Schritte:

# select all `h3` tags with the matching class that are contained within an `a` link. 
# This excludes any random links elsewhere on the page. 
story_headers = soup.select('a > h3.item-heading') 

# Iterate through all the matching `h3` items and access their parent `a` tag. 
# Then, within the parent you have access to the `href` attribute. 
list_of_links = [i.parent.attrs for i in story_headers] 

# Finally, extract the links into a tidy list 
links = [i["href"] for i in list_of_links] 

Sobald Sie die Liste der Links haben, könnten Sie durchlaufen zu prüfen, ob das erste Zeichen ein / ist nur lokale Verbindungen und nicht externe Links zu entsprechen.

+0

Vielen Dank, mein Herr, ich habe mit grundlegenden Webseiten mit BS4 herumgespielt, aber nach dem Aufholen von HTML wollte ich versuchen, um komplexere Seiten zu navigieren. +1 für dich. Danke, dass du mir geholfen hast. Dies wird eine schöne Ergänzung zu meinem Sprachassistenten sein. Für was sind Nachrichtenartikel gut, wenn Sie mit dem Falschen verbunden sind, oder? ;) – Jebby

+0

Gern geschehen. Bitte akzeptiere diese Antwort, wenn es dein Problem gelöst hat, es wird mir die Punkte dafür geben. Danke :) –

+0

Ich bin im Moment nicht zu Hause, also kann ich den Code nicht testen. Wenn ich nach Hause komme, werde ich testen, ob es funktioniert, ich werde die Antwort akzeptieren. – Jebby