Tengo un código de trabajo que raspa las etiquetas 'a href' para las URL y puedo obtener la información de fecha de las etiquetas 'p' anidadas.

<div class='blah'>
    <a href='target_url'></a>
    <p class='date'>Today's date</p> 

En este momento se ve mi código ...

for p in table.find_all('p', {'class':'categoryArticle__meta'}):
    date = p.get_text()
for a in table.find_all('a', href=True)[::2][:-5]:
    headline = a['href']

Me estoy saltando cada dos horas, pero necesito cada cita.

¿Cómo podría unirme a los parámetros de búsqueda para darme la información devuelta, emparejada, es decir, 'target_url', 'Fecha de hoy'?

1
Derek_P 12 may. 2016 a las 01:59

3 respuestas

La mejor respuesta

Si raspa los divs con categoryArticle__content, puede extraer los enlaces y las fechas asociadas:

import  requests
from bs4 import BeautifulSoup
soup = BeautifulSoup(requests.get("http://oilprice.com/Latest-Energy-News/World-News").content)
main_div = soup.select_one("div.tableGrid__column.tableGrid__column--articleContent.category")

divs = main_div.select('div.categoryArticle__content')

print([(d.select_one("p.categoryArticle__meta").text, d.a["href"]) for d in divs])

El texto también incluye más que solo la fecha, por lo que querrá dividir en un char de tubería:

 [(d.select_one("p.categoryArticle__meta").text.split("|")[0].strip(), d.a["href"]) for d in divs]

Lo que te da:

[(u'May 11, 2016 at 17:21', 'http://oilprice.com/Latest-Energy-News/World-News/Oil-Hits-6-Month-High-on-Crude-Inventory-Draw.html'), (u'May 11, 2016 at 16:56', 'http://oilprice.com/Latest-Energy-News/World-News/Nigerian-President-Lashes-Out-At-UK-Over-Stolen-Assets.html'), (u'May 11, 2016 at 15:41', 'http://oilprice.com/Latest-Energy-News/World-News/Germany-Ups-Gazprom-Imports-by-19-percent-in-Q1.html'), (u'May 11, 2016 at 15:39', 'http://oilprice.com/Latest-Energy-News/World-News/Solar-Hits-Millionth-Installation-In-The-US-Faster-Growth-Ahead.html'), (u'May 11, 2016 at 14:14', 'http://oilprice.com/Latest-Energy-News/World-News/OPEC-Production-Up-140000-Bpd-in-April.html'), (u'May 11, 2016 at 14:03', 'http://oilprice.com/Latest-Energy-News/World-News/Tullow-Ghana-Oil-Production-Down-by-More-Than-50.html'), (u'May 11, 2016 at 13:47', 'http://oilprice.com/Latest-Energy-News/World-News/Tesla-To-Complete-Model-3-Design-By-End-June.html'), (u'May 11, 2016 at 12:30', 'http://oilprice.com/Latest-Energy-News/World-News/Iraqi-Kurds-Boost-Oil-Exports-to-Turkey.html'), (u'May 11, 2016 at 11:57', 'http://oilprice.com/Latest-Energy-News/World-News/Security-Services-Raid-Headquarters-of-Ukraines-Largest-Gas-Company.html'), (u'May 11, 2016 at 10:59', 'http://oilprice.com/Latest-Energy-News/World-News/Oil-Up-3-AS-EIA-Reports-34M-Barrel-Crude-Inventory-Drop.html')]

Siempre es mejor asociar valores de la etiqueta principal si es posible, extraer todos los anclajes y cortar no es un enfoque muy sólido.

select y select_one usan css-selectors, el código equivalente usando find y find_all sería:

import requests
from bs4 import BeautifulSoup

soup = BeautifulSoup(requests.get("http://oilprice.com/Latest-Energy-News/World-News").content)
main_div = soup.find("div", class_="tableGrid__column tableGrid__column--articleContent category")
divs = main_div.find_all("div","categoryArticle__content")

print([(d.find("p", {"class": "categoryArticle__meta"}).text.split("|")[0].strip(), d.a["href"]) for d in divs])

class_=.. le permite search-by-css -clase

También en este caso, categoryArticle__content solo aparece en el div principal para que pueda buscar inicialmente esos divs en lugar de seleccionar primero el div principal.

soup = BeautifulSoup(requests.get("http://oilprice.com/Latest-Energy-News/World-News").content)

divs = soup.find_all("div","categoryArticle__content")
print([(d.find("p", {"class": "categoryArticle__meta"}).text.split("|")[0].strip(), d.a["href"]) for d in divs])
2
Padraic Cunningham 11 may. 2016 a las 23:33

Puede convertir las fechas y urls en listas, y luego comprimirlas , así:

dates = []
urls = []
for p in table.find_all('p', {'class':'categoryArticle__meta'}):
    date = p.get_text()
    dates.add(date)
for a in table.find_all('a', href=True)[::2][:-5]:
    headline = a['href'] # should this be called headline?
    urls.add(headline)
easy_access = zip(dates, urls)

Consulte estos para obtener ayuda sobre zip:

Zip convierte las dos listas en una lista de tuplas, por lo que la salida podría verse así:

easy_access = [('1/2/12', 'http://somewhere.com'), 
               ('2/2/12', 'http://somewhereelse.com'), 
               ('3/2/12', 'http://nowhere.com'), 
               ('4/2/12', 'http://here.com')]
-1
Community 23 may. 2017 a las 11:52

Creo que si está tratando de usar una expresión para que coincida para obtener tanto el valor en href como en date, será bastante difícil (es decir, no tengo idea de cómo hacerlo). Sin embargo, si usa xpath para navegar a las partes que desea y almacenarlas, puede elegir fácilmente lo que necesita. Según el código que proporcionó, recomendaría algo como esto:

from lxml import html
import requests

webpage = requests.get('www.myexampleurl.com')
tree = html.fromstring(webpage.content)

currentHRef = tree xpath('//div//a/')[0].get("href")
currentDate = tree.xpath('//div//p/text()')[0]

dateTarget = (currentHRef, currentDate)
-1
Jayson 11 may. 2016 a las 23:22