【问题标题】:How to Find URL on Google Images with Beautiful Soup如何使用 Beautiful Soup 在 Google 图片上查找 URL
【发布时间】:2021-07-29 04:02:54
【问题描述】:

我正在尝试在 Google 上查找无版权的图片,但我无法获得正确的图片网址。我的代码应用了正确的过滤器并将我定向到正确的页面,但是它检索了没有无版权和大小过滤器的图像的 URL,我不确定为什么。提前谢谢你。

import requests
import urllib.request
from bs4 import BeautifulSoup
from urllib.request import urlopen, Request

url = 'https://google.com/search?q='
input = 'cat'
#string: tbm=isch --> means image search
#tbs=isz:m --> size medium
#il:cl --> copy right free(i think)
url = url+input+'&tbm=isch&tbs=isz:m%2Cil:cl'
print(url)
html = urlopen(Request(url, headers={'User-Agent': 'Google Chrome'}))
'''with urllib.request.urlopen(url) as response:
    html = response.read()
    print(html)'''
#print(str(r.content))

soup = BeautifulSoup(html.read(),'html.parser')

#using soup to find all img tags
results = soup.find_all('img')
str_result = str(results)

lst_result = str_result.split(',')
#trying to get the first link for the images with the appropriate settings
link = lst_result[4].split(' ')[4].split('"')[1]

# writing into the appropriate testing file, to be changed
file = open('.img1.png','wb')
get_img = requests.get(link)
file.write(get_img.content)
file.close()

【问题讨论】:

  • 它是从同一页面返回的网址吗?
  • @joey 不,他们不是
  • 他们来自哪个页面?根据您的代码,它们必须来自url+input+'&tbm=isch&tbs=isz:m%2Cil:cl'...如果我是您,我会使用检查元素仔细检查该页面。一旦你知道图像来自哪里,你就会解决问题
  • @joey 他们来自没有无版权过滤器的默认页面,但我不明白为什么
  • 你从哪里得到的网址?当我使用高级搜索时,我得到了 https://www.google.com/search?as_st=y&tbm=isch&hl=en&as_q=cat&as_epq=&as_oq=&as_eq=&imgsz=&imgar=&imgc=&imgcolor=&imgtype=&cr=&as_sitesearch=&safe=images&as_filetype=&tbs=sur%3Acl 用于 cat 和 Creative common liscense

标签: python web-scraping beautifulsoup google-image-search


【解决方案1】:

您可以尝试使用更简单的方法,无需指定tbs=il:cl 参数,并通过搜索“pexels cat”或“unsplash cat”来玩猜谜游戏,哪些图像肯定是在知识共享下获得许可的。

或者,您可以尝试在查询开头添加过滤参数 (tbs=il:cl) 和 pexels/unsplash。

默认情况下,这些图片是完全免费的,因为这些网站旨在为商业或非商业用途提供免费图片,而 Google 只会显示来自这些网站的结果。


要查找和提取原始图像 URL,您需要通过 regex<script> 标记中解析它。

首先你需要找到所有使用bs4的脚本标签:

soup.select('script')

其次,使用regex匹配所需的模式:

# one of the regex patterns to find original size URL
re.findall(r"(?:'|,),\[\"(https:|http.*?)\",\d+,\d+\]", SOME_VARIABLE)

第三,遍历匹配,逐个提取和解码每个 URL:

for SOME_VARIABLE in SOME_VARIABLE:
    # it needs to be decoded twice.
    # otherwise Unicode characters will be still present after the first decode.
    # yes, it is stupid. 
    original_size_img_not_fixed = bytes(fixed_full_res_image, 'ascii').decode('unicode-escape')
    original_size_img = bytes(original_size_img_not_fixed, 'ascii').decode('unicode-escape')

代码和full example in the online IDE that scrapes more

import requests, lxml, re, json
from bs4 import BeautifulSoup

headers = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
}

params = {
    "q": "pexels cat",
    "tbm": "isch",
    "tbs": "il:cl",
    "hl": "en",
    "ijn": "0",
}

html = requests.get("https://www.google.com/search", params=params, headers=headers)
soup = BeautifulSoup(html.text, 'lxml')


def get_images_data():

    print('\nGoogle Images Metadata:')
    for google_image in soup.select('.isv-r.PNCib.MSM1fd.BUooTd'):
        title = google_image.select_one('.VFACy.kGQAp.sMi44c.lNHeqe.WGvvNb')['title']
        source = google_image.select_one('.fxgdke').text
        link = google_image.select_one('.VFACy.kGQAp.sMi44c.lNHeqe.WGvvNb')['href']
        print(f'{title}\n{source}\n{link}\n')

    # this steps could be refactored to a more compact
    all_script_tags = soup.select('script')

    # # https://regex101.com/r/48UZhY/4
    matched_images_data = ''.join(re.findall(r"AF_initDataCallback\(([^<]+)\);", str(all_script_tags)))
    
    # https://kodlogs.com/34776/json-decoder-jsondecodeerror-expecting-property-name-enclosed-in-double-quotes
    # if you try to json.loads() without json.dumps it will throw an error:
    # "Expecting property name enclosed in double quotes"
    matched_images_data_fix = json.dumps(matched_images_data)
    matched_images_data_json = json.loads(matched_images_data_fix)

    # https://regex101.com/r/pdZOnW/3
    matched_google_image_data = re.findall(r'\[\"GRID_STATE0\",null,\[\[1,\[0,\".*?\",(.*),\"All\",', matched_images_data_json)

    # https://regex101.com/r/NnRg27/1
    matched_google_images_thumbnails = ', '.join(
        re.findall(r'\[\"(https\:\/\/encrypted-tbn0\.gstatic\.com\/images\?.*?)\",\d+,\d+\]',
                   str(matched_google_image_data))).split(', ')

    print('Google Image Thumbnails:')  # in order
    for fixed_google_image_thumbnail in matched_google_images_thumbnails:
        # https://stackoverflow.com/a/4004439/15164646 comment by Frédéric Hamidi
        google_image_thumbnail_not_fixed = bytes(fixed_google_image_thumbnail, 'ascii').decode('unicode-escape')

        # after first decoding, Unicode characters are still present. After the second iteration, they were decoded.
        google_image_thumbnail = bytes(google_image_thumbnail_not_fixed, 'ascii').decode('unicode-escape')
        print(google_image_thumbnail)

    # removing previously matched thumbnails for easier full resolution image matches.
    removed_matched_google_images_thumbnails = re.sub(
        r'\[\"(https\:\/\/encrypted-tbn0\.gstatic\.com\/images\?.*?)\",\d+,\d+\]', '', str(matched_google_image_data))

    # https://regex101.com/r/fXjfb1/4
    # https://stackoverflow.com/a/19821774/15164646
    matched_google_full_resolution_images = re.findall(r"(?:'|,),\[\"(https:|http.*?)\",\d+,\d+\]",
                                                       removed_matched_google_images_thumbnails)

    print('\nGoogle Full Resolution Images:')  # in order
    for fixed_full_res_image in matched_google_full_resolution_images:
        # https://stackoverflow.com/a/4004439/15164646 comment by Frédéric Hamidi
        original_size_img_not_fixed = bytes(fixed_full_res_image, 'ascii').decode('unicode-escape')
        original_size_img = bytes(original_size_img_not_fixed, 'ascii').decode('unicode-escape')
        print(original_size_img)

get_images_data()

--------------
'''
Google Images Metadata:
9,000+ Best Cat Photos · 100% Free Download · Pexels Stock Photos
pexels.com
https://www.pexels.com/search/cat/
...

Google Image Thumbnails:
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSb48h3zks_bf6y7HnZGyGPn3s2TAHKKm_7kzxufi5nzbouJcQderHqoEoOZ4SpOuPDjfw&usqp=CAU
...

Google Full Resolution Images:
https://images.pexels.com/photos/1170986/pexels-photo-1170986.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500
...
'''

或者,您可以使用 SerpApi 中的 Google Images API 跳过此过程。这是一个带有免费计划的付费 API。

主要区别在于您只需要迭代结构化 JSON,因为其他所有内容都已为最终用户完成。

要集成的代码:

import os, json # json for pretty output
from serpapi import GoogleSearch


def get_google_images():
    params = {
      "api_key": os.getenv("API_KEY"),
      "engine": "google",
      "q": "minecraft shaders 8k photo",
      "tbm": "isch"
    }

    search = GoogleSearch(params)
    results = search.get_dict()

    print(json.dumps(results['images_results'], indent=2, ensure_ascii=False))

----------
'''
...
  {
    "position": 60, # img number
    "thumbnail": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRt-tXSZMBNLLX8MhavbBNkKmjJ7wNXxtdr5Q&usqp=CAU",
    "source": "pexels.com",
    "title": "1,000+ Best Cats Videos · 100% Free Download · Pexels Stock Videos",
    "link": "https://www.pexels.com/search/videos/cats/",
    "original": "https://images.pexels.com/videos/855282/free-video-855282.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    "is_product": false
  }
...
'''

附: - 我写了一篇关于抓取 Google Images 的博客文章,其中更深入地介绍了视觉表示。

免责声明,我为 SerpApi 工作。

【讨论】:

    猜你喜欢
    • 2020-10-24
    • 1970-01-01
    • 2017-10-22
    • 2016-01-13
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    相关资源
    最近更新 更多