【问题标题】:Scraping images in a dynamic, JavaScript webpage using Scrapy and Splash使用 Scrapy 和 Splash 在动态 JavaScript 网页中抓取图像
【发布时间】:2021-06-24 19:28:17
【问题描述】:

我正在尝试抓取来自this link 的高分辨率图像的链接,但只有单击页面,即点击后“点击这里放大图片”(在页面上,它是土耳其语)。
然后我可以使用 Chrome 的“开发者工具”检查它并获取 xpath/css 选择器。到目前为止一切都很好。

但是,您知道在 JS 页面中,您只是无法键入 response.xpath("//blah/blah/@src") 并获取一些数据。我安装 Splash(使用 Docker pull)并配置我的 Scrapy setting.py 文件等以使其工作(这个 YouTube link 帮助。除非你想学习如何做,否则无需访问链接)。 ...并且它适用于其他 JS 网页!

只是...我无法通过这个“单击此处放大图片!” 的事情并得到响应。它给了我null 的响应。

这是我的代码:

import scrapy
#import json
from scrapy_splash import SplashRequest

class TryMe(scrapy.Spider):
    name = 'try_me'
    allowed_domains = ['arabam.com']

    def start_requests(self):
        start_urls = ["https://www.arabam.com/ilan/sahibinden-satilik-hyundai-accent/bayramda-arabasiz-kalmaa/17753653",
        ]

        for url in start_urls:
            yield scrapy.Request(url=url, 
            callback=self.parse, 
            meta={'splash': {'endpoint': 'render.html', 'args': {'wait': 0.5}}})
            # yield SplashRequest(url=url, callback=self.parse)  # this works too

    def parse(self, response):
        ## I can get this one's link successfully since it's not between js codes:
        #IMG_LINKS = response.xpath('//*[@id="js-hook-for-ing-credit"]/div/div/a/img/@src').get() 
        ## but this one just doesn't work:      
        IMG_LINKS = response.xpath("/html/body/div[7]/div/div[1]/div[1]/div/img/@src").get()
        print(IMG_LINKS)  # prints null :(
        yield {"img_links":IMG_LINKS}  # gives the items: img_links:null

我正在使用的 Shell 命令:
scrapy crawl try_me -O random_filename.jl

我要抓取的链接的 Xpath:
/html/body/div[7]/div/div[1]/div[1]/div/img

Image of this Xpath/link

当我点击放大时,我实际上可以在我的开发者工具窗口网络标签上看到我想要的链接,但我不知道如何从该标签中>抓取该链接。

可能的解决方案:我还将尝试获取我的回复的整个乱码,即response.text并应用正则表达式(例如以https://...开头并以.jpg) 结尾。这肯定是大海捞针,但听起来也很实用。

谢谢!

【问题讨论】:

    标签: python xpath scrapy web-crawler scrapy-splash


    【解决方案1】:

    据我了解,您希望找到主图片链接。我检查了页面,它在 meta 元素之一内:

    <meta itemprop="image" content="https://arbstorage.mncdn.com/ilanfotograflari/2021/06/23/17753653/3c57b95d-9e76-42fd-b418-f81d85389529_image_for_silan_17753653_1920x1080.jpg">
    
    

    你可以得到什么

    >>> response.css('meta[itemprop=image]::attr(content)').get()
    'https://arbstorage.mncdn.com/ilanfotograflari/2021/06/23/17753653/3c57b95d-9e76-42fd-b418-f81d85389529_image_for_silan_17753653_1920x1080.jpg'
    

    您不需要为此使用 splash。如果我用 splash 检查网站,arabam.com 会给出权限被拒绝错误。我建议不要在这个网站上使用 splash。

    为了更好地解决所有图像,您可以解析 javascript。图片数组在源代码中加载了js。

    要联系该 javascript,请尝试:

      response.css('script::text').getall()[14]
    

    这将为您提供包含图像数组的整个 javascript 字符串。您可以使用 js2xml 等内置库对其进行解析。

    在此处查看如何使用它https://github.com/scrapinghub/js2xml。如果还有问题,可以提问。祝你好运

    【讨论】:

    • 1) 我用js2xml.parse(...) 解析了您的最后一个代码(带有[14] 的代码)2) js2xml.pretty_print(...) 它并找到了所需jpg 的路径。 3) 使用 xpath 选择器提取链接:parsed.xpath("//object/property[@name='src']/string/text()") 4) Viola!非常感谢! PS:我也用特定的正则表达式模式解决了它,但我认为当你在图像链接上找不到任何逻辑字符串模式时,你的可以应用于任何网页。
    • 没错!如果页面加载了内联 css,您可以解析 javascript 字符串,否则,splash 很有帮助。很高兴它有帮助)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多