Python - 使用Selenium访问React Props

时间:2018-02-15 19:23:58

标签: python reactjs selenium

注意:可以是任何解决方案,硒似乎是最有可能解决此问题的工具。

Imgur有相册,相册的图片链接存储在(一个React元素?)GalleryPost.album_image_store._.posts.{ALBUM_ID}.images中(感谢this guy来解决这个问题。)

对chrome使用React DevTools扩展名,我可以看到这个图像链接数组,但我希望能够从python脚本中访问它。

任何想法如何?

P.S。我根本不了解反应,所以请原谅我这是一个愚蠢的问题,还是可能使用不正确的术语。

以下是我一直在使用的相册:https://imgur.com/a/JNzjB

已实施解决方案:

非常感谢Eduard Florinescu与我合作解决所有问题。我对硒几乎一无所知,如何在selenium中运行javascript,或者我可以使用的任何命令。

修改他的一些代码,我最终得到了以下内容。

from time import sleep

from bs4 import BeautifulSoup
from selenium import webdriver  
from selenium.webdriver.chrome.options import Options


# Snagged from: https://stackoverflow.com/a/480227
def rmdupe(seq):
    # Removes duplicates from list
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]


chrome_options = Options()  
chrome_options.add_argument("--headless")  

prefs = {"profile.managed_default_content_settings.images":2}
chrome_options.add_experimental_option("prefs",prefs)

driver = webdriver.Chrome(chrome_options=chrome_options)
driver.set_window_size(1920, 10000)
driver.get("https://imgur.com/a/JNzjB")


links = []
for i in range(0, 10):  # Tune as needed
    soup = BeautifulSoup(driver.page_source, 'html.parser')
    for div in soup.find_all('div', {'class': 'image post-image'}):
        imgs = div.find_all('img')
        for img in imgs:
            srcs = img.get_attribute_list('src')
            links.extend(srcs)
        sources = div.find_all('source')
        for s in sources:
            srcs = s.get_attribute_list('src')
            links.extend(srcs)
    links = rmdupe(links)  # Remove duplicates
    driver.execute_script('window.scrollBy(0, 750)')
    sleep(.2)

>>> len(links)
# 36 -- Huzzah! Got all the album links!

注意:

  • 创建一个无头的chrome实例,因此代码可以实现 脚本或可能是更大的项目。

  • 我使用了BeautifulSoup,因为它更易于使用,而且我是 在查找元素和访问其值时遇到一些问题 使用硒(可能是由于经验不足)。

  • 将显示尺寸设置为真正"高"所以更多的图像链接 立刻加载。

  • 要停止的Chrome浏览器设置中的已禁用图像 实际下载图像的浏览器(我需要的只是 链接)。

  • 某些链接是.mp4文件,并以html格式呈现为video 包含<source>标签的元素,其中包含 链接。以sources = div.find_all('source')开头的代码部分用于确保没有相册链接 丢失。

1 个答案:

答案 0 :(得分:1)

您不需要知道任何自动化任何页面的框架。您只需要访问DOM,就可以使用selenium和python来实现。但有时一些简单的Vanilla JavaScript会有所帮助。

要获取这些链接,您可以尝试将其粘贴到控制台中:

images_links =[]; images = document.querySelectorAll("img"); for (image of images){images_links.push(image.src)} console.log(images_links)

使用python的selenium和上面的JS片段是:

import selenium
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()

driver.get("https://imgur.com/a/JNzjB")
for i in range(0,7): # here you will need to tune to see exactly how many scrolls you need
  driver.execute_script('window.scrollBy(0, 2000)')

sleep(2)
list_of_images_links=driver.execute_script('images_links =[]; images = document.querySelectorAll("img"); for (image of images){images_links.push(image.src)} return images_links;')
list_of_images_links

enter image description here

更新

你不需要selenium只需将其粘贴到Opera控制台中(参见你启用了多个下载)并且瞧:

document.body.style.zoom=0.1; images=document.querySelectorAll("img"); for (i of images) { var a = document.createElement('a'); a.href = i.src; console.log(i); a.download = i.src; document.body.appendChild(a); a.click(); document.body.removeChild(a); }

同样美化阅读:

document.body.style.zoom=0.1;
images = document.querySelectorAll("img");
for (i of images) {
    var a = document.createElement('a');
    a.href = i.src;
    console.log(i);
    a.download = i.src;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
}

更新2 Opera webdriver

import os
from time import sleep
from selenium import webdriver
from selenium.webdriver.common import desired_capabilities
from selenium.webdriver.opera import options

_operaDriverLoc = os.path.abspath('c:\\Python27\\Scripts\\operadriver.exe')  # Replace this path with the actual path on your machine.
_operaExeLoc = os.path.abspath('c:\\Program Files\\Opera\\51.0.2830.34\\opera.exe')   # Replace this path with the actual path on your machine.

_remoteExecutor = 'http://127.0.0.1:9515'
_operaCaps = desired_capabilities.DesiredCapabilities.OPERA.copy()

_operaOpts = options.ChromeOptions()
_operaOpts._binary_location = _operaExeLoc

# Use the below argument if you want the Opera browser to be in the maximized state when launching.
# The full list of supported arguments can be found on http://peter.sh/experiments/chromium-command-line-switches/
_operaOpts.add_argument('--start-maximized')

driver = webdriver.Chrome(executable_path = _operaDriverLoc, chrome_options = _operaOpts, desired_capabilities = _operaCaps)


driver.get("https://imgur.com/a/JNzjB")
for i in range(0,7): # here you will need to tune to see exactly how many scrolls you need
  driver.execute_script('window.scrollBy(0, 2000)')

sleep(4)
driver.execute_script("document.body.style.zoom=0.1")
list_of_images_links=driver.execute_script('images_links =[]; images = document.querySelectorAll("img"); for (image of images){images_links.push(image.src)} return images_links;')
list_of_images_links
driver.execute_script('document.body.style.zoom=0.1; images=document.querySelectorAll("img"); for (i of images) { var a = document.createElement("a"); a.href = i.src; console.log(i); a.download = i.src; document.body.appendChild(a); a.click(); document.body.removeChild(a); }')