javascript - scraping - ¿Cómo ceder fragmentos de URL en el tratamiento con Selenium?
selenium webdriver python download (3)
de mi poco conocimiento sobre webscraping, he llegado a encontrar un problema muy complejo para mí, intentaré explicar lo mejor que pueda (por lo tanto, estoy abierto a sugerencias o ediciones en mi publicación).
Comencé a utilizar el marco de rastreo web '' Scrapy '' hace mucho tiempo para hacer mi webscraping, y sigue siendo el que uso hoy en día. Últimamente, me encontré con este sitio web , y descubrí que mi framework ( Scrapy ) no podía iterar sobre las páginas ya que este sitio web usa Fragment URLs
(#) para cargar los datos (las siguientes páginas). Luego hice una publicación sobre ese problema (sin tener idea del problema principal todavía): mi publicación
Después de eso, me di cuenta de que mi framework no podía funcionar sin un intérprete de JavaScript
o una imitación de navegador, por lo que mencionaron la biblioteca de Selenium
. Leí todo lo que pude sobre esa biblioteca (es decir, ejemplo1 , ejemplo2 , ejemplo3 y ejemplo4 ). También encontré esta publicación de StackOverflow que da algunas pistas sobre mi problema.
Entonces, finalmente, mis preguntas más importantes son:
1 - ¿Hay alguna forma de iterar / ceder sobre las páginas del sitio web que se muestra arriba, usando Selenium junto con scrapy? Hasta ahora, este es el código que estoy usando, pero no funciona ...
EDITAR:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# The require imports...
def getBrowser():
path_to_phantomjs = "/some_path/phantomjs-2.1.1-macosx/bin/phantomjs"
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/53 "
"(KHTML, like Gecko) Chrome/15.0.87")
browser = webdriver.PhantomJS(executable_path=path_to_phantomjs, desired_capabilities=dcap)
return browser
class MySpider(Spider):
name = "myspider"
browser = getBrowser()
def start_requests(self):
the_url = "http://www.atraveo.com/es_es/islas_canarias#eyJkYXRhIjp7ImNvdW50cnlJZCI6IkVTIiwicmVnaW9uSWQiOiI5MjAiLCJkdXJhdGlvbiI6NywibWluUGVyc29ucyI6MX0sImNvbmZpZyI6eyJwYWdlIjoiMCJ9fQ=="
yield scrapy.Request(url=the_url, callback=self.parse, dont_filter=True)
def parse(self, response):
self.get_page_links()
def get_page_links(self):
""" This first part, goes through all available pages """
for i in xrange(1, 3): # 210
new_data = {"data": {"countryId": "ES", "regionId": "920", "duration": 7, "minPersons": 1},
"config": {"page": str(i)}}
json_data = json.dumps(new_data)
new_url = "http://www.atraveo.com/es_es/islas_canarias#" + base64.b64encode(json_data)
self.browser.get(new_url)
print "/nThe new URL is -> ", new_url, "/n"
content = self.browser.page_source
self.get_item_links(content)
def get_item_links(self, body=""):
if body:
""" This second part, goes through all available items """
raw_links = re.findall(r''listclickable.+?>'', body)
links = []
if raw_links:
for raw_link in raw_links:
new_link = re.findall(r''data-link=/".+?/"'', raw_link)[0].replace("data-link=/"", "").replace("/"",
"")
links.append(str(new_link))
if links:
ids = self.get_ids(links)
for link in links:
current_id = self.get_single_id(link)
print "/nThe Link -> ", link
# If commented the line below, code works, doesn''t otherwise
yield scrapy.Request(url=link, callback=self.parse_room, dont_filter=True)
def get_ids(self, list1=[]):
if list1:
ids = []
for elem in list1:
raw_id = re.findall(r''/[0-9]+'', elem)[0].replace("/", "")
ids.append(raw_id)
return ids
else:
return []
def get_single_id(self, text=""):
if text:
raw_id = re.findall(r''/[0-9]+'', text)[0].replace("/", "")
return raw_id
else:
return ""
def parse_room(self, response):
# More scraping code...
Así que este es principalmente mi problema. Estoy casi seguro de que lo que estoy haciendo no es la mejor manera, entonces hice mi segunda pregunta. Y para evitar tener que hacer este tipo de problemas en el futuro, hice mi tercera pregunta.
2 - Si la respuesta a la primera pregunta es negativa, ¿cómo podría abordar este problema? Estoy abierto a otro medio, de lo contrario
3 - ¿Alguien puede decirme o mostrarme páginas donde puedo aprender a resolver / combinar webscraping a lo largo de javaScript y Ajax? Hoy en día son más los sitios web que usan scripts de JavaScript y Ajax para cargar contenido
¡Muchas gracias de antemano!
¿Has investigado BeautifulSoup ? Es una biblioteca de raspado web muy popular para Python. En cuanto a JavaScript, recomendaría algo así como Cheerio (si estás pidiendo una biblioteca raspante en JavaScript)
Si quiere decir que el sitio web utiliza solicitudes HTTP para cargar contenido, siempre puede intentar manipularlo manualmente con algo como la biblioteca de solicitudes .
Espero que esto ayude
Definitivamente puede usar Selenium como un dispositivo independiente para eliminar páginas web con contenido dinámico (como la carga de AJAX).
Selenium solo confiará en un WebDriver (básicamente un navegador web) para buscar contenido a través de Internet.
Estos son algunos de ellos (pero los más utilizados) :
- ChromeDriver
- PhantomJS (mi favorito)
- Firefox
Una vez que haya comenzado, puede iniciar su bot y analizar el contenido html de la página web.
Incluí un ejemplo de trabajo mínimo a continuación usando Python y ChromeDriver:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome(executable_path=''chromedriver'')
driver.get(''https://www.google.com'')
# Then you can search for any element you want on the webpage
search_bar = driver.find_element(By.CLASS_NAME, ''tsf-p'')
search_bar.click()
driver.close()
¡Vea la documentación para más detalles!
El selenio es una de las mejores herramientas para eliminar datos dinámicos. Puedes usar selenio con cualquier navegador web para buscar los datos que se cargan desde los scripts. Esto funciona exactamente igual que las operaciones de clic del navegador. Pero no lo estoy prefiriendo.
Para obtener datos dinámicos puede usar scrapy + splash combo. Desde scrapy obtendrás todos los datos estáticos y salpicaduras para otros contenidos dinámicos.