selenium 为什么我的脚本停止时,从网页上报废的img?

p4rjhz4m  于 2023-03-30  发布在  其他
关注(0)|答案(3)|浏览(85)

bounty将在10小时后过期。回答此问题可获得+50声望奖励。N7Legend希望引起更多人关注此问题。

我目前正在尝试使用一个脚本来丰富机器学习的数据集,该脚本允许我从谷歌下载图像。
我首先浏览一个包含要在谷歌上搜索的字段的 Dataframe ,然后使用selenium webdriver检索要下载的图像的URL,并通过此函数将它们保存在特定的文件夹中,具体取决于字段:

def download_image(file_path, url, file_name):
    try:
        response = requests.get(url)
        response.raise_for_status()
        with open(os.path.join(file_path, file_name), 'wb') as file:
            file.write(response.content)
        print(f"Image downloaded successfully to {os.path.join(file_path, file_name)}")
    except requests.exceptions.HTTPError as http_error:
        print(f"HTTP error occurred: {http_error}")
    except Exception as error:
        print(f"An error occurred: {error}")

在这个循环中叫做:

def enhanced_dataset_folder(name:str, tag:str, df):
    DRIVER_PATH = "chromedriver"
    wd = webdriver.Chrome(DRIVER_PATH)
    urls = get_images(tag, wd, 1, 2)
    folder_name = name.split('/')[0]
    props = tag.split(' ')
    test = []
    for i, url in enumerate(urls):
        try:
            img_name = str(i) + "_img"+str(i)+".jpg"
            download_image("train/"+folder_name+"/", url, img_name)
        except Exception as e:
            print('Fail: ', e)
            continue
        else:
            print("ok")
            #df.append([folder_name+"/"+img_name,tag,props[0],props[1],props[2]], ignore_index=True)
    wd.quit()

google chrome窗口和脚本总是同时停止,不管我每页得到多少张照片。我有这个输出,但没有错误出来:

Image downloaded successfully to train/1982 Porsche 944/0_img0.jpg
ok
Image downloaded successfully to train/1982 Porsche 944/1_img1.jpg
ok
HTTP error occurred: 403 Client Error: Forbidden. Please comply with the User-Agent policy: https://meta.wikimedia.org/wiki/User-Agent_policy for url: https://upload.wikimedia.org/wikipedia/commons/1/13/1986_944_Turbo.jpg
ok
Image downloaded successfully to train/1996 Ferrari 550 Maranello/0_img0.jpg
ok
Image downloaded successfully to train/1996 Ferrari 550 Maranello/1_img1.jpg
ok
Image downloaded successfully to train/1996 Ferrari 550 Maranello/2_img2.jpg
ok
Image downloaded successfully to train/2001 BMW 3 Series Convertible/0_img0.jpg
ok

我知道问题出在download_image函数上,因为当我不调用它时,每次出现 Dataframe 时都会检索url

z18hc3ub

z18hc3ub1#

阅读错误消息非常有用:

HTTP error occurred: 403 Client Error: Forbidden. 
    Please comply with the User-Agent policy: https://meta.wikimedia.org/wiki/User-Agent_policy 
    for url: https://upload.wikimedia.org/wikipedia/commons/1/13/1986_944_Turbo.jpg

你显然违反了网站的政策。为了保护自己,他们可以采取任何对策,因为他们喜欢,也发送虚假内容给你。
在这种情况下(wikimedia.org),他们告诉你他们将如何接受你报废他们的文件:https://meta.wikimedia.org/wiki/User-Agent_policy
他们希望有一个合适的用户代理,允许他们对访问进行分类并与您联系。他们敦促您发送一个合适的代理字符串,以将您识别为个人,可识别的机器人。-否则他们会采取对策。
他们期望agent-string中包含单词“bot”。agent-string的语法期望:

<client name>/<version> (<contact information>) <library/framework name>/<version> [<library name>/<version> ...]

# Example:
User-Agent: CoolBot/0.0 (https://example.org/coolbot/; coolbot@example.org) generic-library/0.0

对于Python,他们还给予了一个示例代码片段:

import requests

url = 'https://example/...'
headers = {'User-Agent': 'CoolBot/0.0 (https://example.org/coolbot/; coolbot@example.org)'}

response = requests.get(url, headers=headers)

所以我建议

  • 为你的机器人设置一个网页作为联系页面/电子名片,包括一个电子邮件地址。一个关于你的项目的小介绍可能会有帮助。
  • 自定义代理字符串以识别关键字“bot”、您的意图和联系页面

然后给予机器人一个运行和告诉,如果事情变得更好。

关于403 - Forbidden

这是对GET或POST请求的限定响应。通过这个响应,HTTP请求完成,您的脚本必须决定下一步要做什么。
=〉脚本决定在写入日志后继续。
如果你被阻止了(例如,通过你的IP地址的访问规则),你会看到403对这个服务器的每一次访问。
=〉在此日志文件中不是这种情况。
当访问受限资源时会出现“禁止”。当您从Google搜索URL时,可能会出现指向受限文件的URL,因为这些URL可能会发布在网站的公共区域。
403第一眼看起来没什么特别的。
403作为触发器的可能性是403命中的组合,随后是同一站点(或由同一人托管的站点)定期出现的问题。
=〉关于这些403的更多细节与问题相结合将是很好的。
当你写的时候,问题消失了:你改变了什么
或者你只是得到了一个新的搜索结果形式谷歌优先考虑其他网站?

您问题的答案

您的陈述显著增加了导致403的URL作为触发器URL的可能性:
我没有改变任何东西,除了绕过导致第一个403错误的URL,这导致我的脚本停止。我还没有找到这个算法的最佳行为,但这个解决方案允许我丰富我的数据集
通过这样做,你绕过了触发器。
对于您的项目来说,避免这个问题的最好方法是获得废弃网站的认可(见上文)。
当他们注意到他们的触发器被发现并绕过时,他们会选择另一个URL作为触发器,然后游戏重新启动。-当您的IP(-range)或指纹配置文件被列入黑名单时,不要感到惊讶。

总结

问题不是来自您的代码,而是来自bot工具及其设置。违反使用策略将引起React,这是互联网上的常见效果。

  • (我肯定你不喜欢这个答案)*
o2gm4chl

o2gm4chl2#

此错误消息...

HTTP error occurred: 403 Client Error: Forbidden. Please comply with the User-Agent policy: https://meta.wikimedia.org/wiki/User-Agent_policy for url: https://upload.wikimedia.org/wikipedia/commons/1/13/1986_944_Turbo.jpg

...表示访问有效URL时遇到HTTP403 Forbidden响应状态码。

深度挖掘

可能这与我们已经讨论了很长时间的Invalid Status code=403 text=Forbidden问题相同。
溶液
一个全面的解决方案是通过Options的示例添加参数 --remote-allow-origins=*,如下所示:

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

options = Options()
options.add_argument("--remote-allow-origins=*")
DRIVER_PATH = "chromedriver"
wd = webdriver.Chrome(executable_path=DRIVER_PATH, options=options)
muk1a3rh

muk1a3rh3#

您正在以同步模式调用HTTP服务器,这意味着当套接字连接时,您的脚本将等待直到接收到数据并关闭连接,或者您已按下^C。这是您尝试使用的服务的防火墙/Web服务器实现的技巧。
您可以切换到aiohttp,以便能够在异步模式下执行多个调用。您需要小心地调整连接速率,并在调用之间引入一些适当的间隙。以下答案可能会帮助您:aiohttp: rate limiting parallel requests
您可以在创建一组请求后使用asyncio.sleep,如果它们没有在预期的时间内完成,您可以 * 删除 * 未来的对象-这实际上意味着您正在删除您的连接。

相关问题