【问题标题】:Scrape images from 9gag, unable to read correct HTML-page从 9gag 抓取图像,无法读取正确的 HTML 页面
【发布时间】:2019-11-22 07:56:15
【问题描述】:

我正在尝试编写一个脚本,该脚本将只为图像和图像刮取 9gag。但是我遇到了一个问题,即我的请求或 Beautifulsoup 获取了错误的 HTML 页面。 Beautifulsoup 当前正在获取源页面,而不是包含图像的页面。
为什么 Beautifulsoup 会排除包含实际图像的类?还是不同的 HTML 页面?

我已经为 Beautiful soup“解析器”尝试了不同的格式,但仍然得到错误的页面。

如果您转到 9gag 并右键单击和“检查”,您可以访问图像,以及使用脚本提取图像的页面。

我的脚本:

import requests
from bs4 import BeautifulSoup
import os


def download_image(url, fileName):          #save image function
    path = os.path.join("imgs", fileName)
    f = open(path, 'wb')
    f.write(requests.get(url).content)
    f.close()


def fetch_url(url):                        # fetching url
    page = requests.get(url)
    return page

def parse_html(htmlPage):                  #parsing the url
    soup = BeautifulSoup(htmlPage, "html.parser")
    return soup


def retrieve_jpg_urls(soup):

    list_of_urls = soup.find_all('list')       #classes wanted
    parsed_urls = []
    for index in range(len(list_of_urls)):
        try:
            parsed_urls.append(soup.find_all('img')[index].attrs['src']) #img wanted inside class
        except:
            next
    return parsed_urls


def main():
    htmlPage = fetch_url("https://9gag.com/")
    soup = parse_html(htmlPage.content)
    jpgUrls = retrieve_jpg_urls(soup)
    for index in range(len(jpgUrls)):
        try:
            download_image(jpgUrls[index], "savedpic{}.jpg".format(index))
        except:
            print("failed to parse image with url {}".format(jpgUrls[index]))
    print("")

if __name__ == "__main__":
    main()

Beautifulsoup 得到了什么:

<!DOCTYPE html>

<html lang="en">
<head>
<title>9GAG: Go Fun The World</title>
<link href="https://assets-9gag-fun.9cache.com" rel="preconnect"/>
<link href="https://img-9gag-fun.9cache.com" rel="preconnect"/>
<link href="https://miscmedia-9gag-fun.9cache.com" rel="preconnect"/>
<link href="https://images-cdn.9gag.com/img/9gag-og.png" rel="image_src"/>
<link href="https://9gag.com/" rel="canonical"/>
<link href="android-app://com.ninegag.android.app/http/9gag.com/" rel="alternate"/>
<link href="https://assets-9gag-fun.9cache.com/s/fab0aa49/5aa8c9f45ee3dd77f0fdbe4812f1afcf5913a34e/static/dist/core/img/favicon.ico" rel="shortcut icon"/>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
<meta content="9GAG has the best funny pics, gifs, videos, gaming, anime, manga, movie, tv, cosplay, sport, food, memes, cute, fail, wtf photos on the internet!" name="description"/> 

我想要以下:

<img src="https://img-9gag-fun.9cache.com/photo/aLgyG2V_460s.jpg" alt="There&amp;#039;s genuine friend love there" style="min-height: 566.304px;">

【问题讨论】:

  • 9gag 是否使用 JavaScript 加载图像?如果是这样,您将不得不采取另一种方法,因为请求不会执行 JavaScript。
  • 是的,我认为它可能会......图像嵌入在一个使用 javascript 加载的类中
  • 你不能仅仅通过解析HTML得到你想要的图像,因为图像是用JS加载的。但是,您可以使用 re 模块来提取页面上的 JSON。在 HTML 中搜索 window._config = JSON.parse(
  • 使用requests_html库,会渲染javascript
  • 查看 Seleniumdryscrape 以获取 JS 支持。另请参阅 this answer 以获取有关示例的更多帮助。请注意,Selenium 需要显示器。要无头运行,请参阅我的回答 here

标签: python image web-scraping beautifulsoup


【解决方案1】:

尝试提取页面上的 JSON:

import re
import json

# ...
res = requests.get(...)
html = res.content

m = re.search('JSON\.parse\((.*)\);</script>', html)
double_encoded = m.group(1)
encoded = json.loads(double_encoded)
parsed = json.loads(encoded)

images = [p['images']['image700']['url'] for p in parsed['data']['posts']]
print(images)

输出:

['https://img-9gag-fun.9cache.com/photo/abY9Wg8_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/aLgy4o5_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/aE2LVeM_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/amBEGb4_700b.jpg', 'https://img-9gag-fun.9cache.com/photo/aKxrv56_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/a5M8wXN_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/aNY6QEv_700b.jpg', 'https://img-9gag-fun.9cache.com/photo/aYY2Deq_700b.jpg', 'https://img-9gag-fun.9cache.com/photo/aQR0AEw_460s.jpg', 'https://img-9gag-fun.9cache.com/photo/aLgy19P_700b.jpg']

【讨论】:

  • 输入代码时出现以下错误@abdusco: TypeError: cannot use a string pattern on a bytes-like object
  • 尝试将 res.content 更改为 res.text 以获取解码的 HTML。
  • 开始工作了!非常感谢!你知道是否可以提取图像的标题、赞成票和大小? @abdusco
  • 您可能需要为此访问各个页面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-30
  • 2012-11-24
  • 2015-04-05
  • 2018-03-20
  • 2016-11-16
  • 2018-11-06
  • 1970-01-01
相关资源
最近更新 更多