我正在开发一个使用硒的小型网络抓取项目,其中我从服装网站上抓取了一些产品信息:(https://www.asos.com/us/search/?q=shirt),我'经过相当多的尝试和错误后,我已经能够获得大部分产品信息,但我在从页面源中抓取 src 图像时遇到了一些问题 - 我认为这在方法上与我所经历的其他事情相对相似能够获取产品名称、价格、产品页面的网址等。以下是我尝试从页面中抓取图像的代码片段:
imgsSrc = set()
containers = driver.find_elements(By.CLASS_NAME, "productMediaContainer_kmkXR")
for container in containers:
image = container.find_element(By.TAG_NAME, 'img')
print(image.get_attribute('src'))
imgsSrc.add(image.get_attribute('src'))
这适用于大约前 8 个产品的给予或接受,但是它随后失败 - 至少从我能够找到类似情况的信息来看,这可能是由于该网站对 img 标签类使用“延迟加载” 。页面源上的产品通常 ~ 第 8 个产品条目具有不同的图像标签类,其效果为: 等等,我认为这是它无法获取其余图像的地方,因为它们都属于此类.
我不确定这是否重要,但就我而言,在抓取页面上的任何内容之前,我的程序还会单击页面上的“加载更多”按钮,直到(如果可能)显示约 216 个产品,并将用于产品的过滤器设置为用户输入的过滤器。
我尝试过的一些事情是让驱动程序在抓取图像之前滚动到页面末尾,但我不确定图像是否仅在位于视口中时才加载到页面源上.
根据我的理解,我从每个产品中提取的 div 类(“productMediaContainer_kmkXR”)不是延迟加载的,但其中包含的 img 类可能是延迟加载的。 (也有可能不是 img 标签,而是与产品关联的视频类标签,该产品在名为“海报”的成员中仍然具有图像,如下所示:)
目前,我只是想弄清楚如何获取页面上产品的所有图像。我只是不确定这是否是由于在抓取时没有逐渐滚动页面或其他原因造成的。
经过大量测试弗兰肯斯坦对类似问题的各种解决方案,以下是我出于我的目的而找到的解决方案:
首先,我的问题似乎是我需要用足够慢的网络驱动程序完全滚动页面,以便每个图像都可以加载,因为我相信它们确实是延迟加载的,以下代码片段是我以前这样做的,有点慢但可能会调整得更快并且仍然有效:
imgsSrc = []
driver.execute_script("window.scrollTo(0, 0);") #Go to top of page
SCROLL_PAUSE_TIME = 2 #How long to wait between scrolls
while True:
previous_scrollY = driver.execute_script('return window.scrollY')
#driver.execute_script('window.scrollBy( 0, 400 )' ) #Alternative scroll, a bit slower but reliable
html = driver.find_element(By.TAG_NAME, 'html')
html.send_keys(Keys.PAGE_DOWN)
html.send_keys(Keys.PAGE_DOWN)
html.send_keys(Keys.PAGE_DOWN) #Faster scroll, inelegant but works (Could translate to value scroll like above)
time.sleep(SCROLL_PAUSE_TIME) #Give images a bit of time to load by waiting
# Calculate new scroll height and compare with last scroll height
if previous_scrollY == driver.execute_script('return window.scrollY'):
break
这应该缓慢滚动到页面底部,这样做允许加载容器中的图像以进行抓取,正如我最初提到的,我知道我用于测试的特定页面可能有视频标签而不是图像,但是可以从名为“poster”的成员变量中提取图像,以下是我处理抓取图像和处理视频案例的方式:
missingCount = 0 #How many images did we miss (Testing purposes)
containers = driver.find_elements(By.CLASS_NAME, "productMediaContainer_kmkXR")
print(len(containers)) #Make sure we're getting all the containers
for container in containers:
try:
image = container.find_element(By.TAG_NAME, 'img')
print(image.get_attribute('src'))
imgsSrc.append(image.get_attribute('src'))
except NoSuchElementException: #Ideally in this case it's a video rather than an image (otherwise we didn't give it time to load)
print("Whoops - Check if video")
try:
image = container.find_element(By.TAG_NAME,'video')
print(image.get_attribute('poster'))
imgsSrc.append(image.get_attribute('poster'))
except NoSuchElementException: #It wasn't a video - OR we didn't give it enough time to load
missingCount += 1
print("We're really broken")
print(missingCount)
感谢大家的回答,祝未来偶然发现这一点的读者好运 - 我希望这对我有帮助,就我而言,我必须做大量的故障排除并将其他人遇到的类似问题拼凑在一起。