[Errno 13] Permission denied при парсинге картинок

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Win7x64, Python3.7
Добрый день. Написаны два парсера на один и тот же сайт, один на requests, другой на requests_html, первый использует BS, второй xpath. Все функции аналогичны, просто переписаны с учетом используемых либ. Проблема в том, что при парсинге картинок первый парсер отрабатывает хорошо(создаются папки под каждую статью и в эту папку сохраняются картинки, правда изредка случается [Errno 2] No such file or directory: 'название папки /имя файла.jpg' <class 'FileNotFoundError'> и эта папка оказывается пустой) , а второй падает с ошибкой
[Errno 13] Permission denied, папки для картинок создаются, но они пустые. Оба скрипта запускаются из одной и той же папки одной и той же консолью. В чем может быть проблема?
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
[Errno 13] Permission denied
Попробуйте запускать консоль от имени администратора.
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Попробуйте запускать консоль от имени администратора.
Screenshot_5.png

консоль всегда с админ правами запускается
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
консоль всегда с админ правами запускается
не всегда можно просто запустить cmd.exe, а можно от имени администратора.
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
не всегда можно просто запустить cmd.exe, а можно от имени администратора.
нет, к сожалению не работает и от администратора(
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Покажите код (возможно у вас там одновременный доступ к файлу и возникает блокировка).
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Python:
# -*- coding: utf-8 -*-
# !/usr/bin/env python3


from requests_html import HTMLSession
from lxml import html
import codecs
import re
import os


DOMAIN = 'https://site.ru'
headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
    }


def get_html(session,  url):  #
    response = session.get(url, headers=headers)
    response.encoding = 'utf8'
    html_code = response.text
    return html_code


def get_folder(session, url):  #
    html_code = get_html(session, url)
    dom_tree = html.fromstring(html_code)

    folder = dom_tree.xpath('//title')[0].text
    folder = re.sub('\W+',' ', folder) # удаляет спецсимволы из строки
    if len(folder) >= 45:
        folder = folder[:45]
    if not os.path.exists(folder):
        os.makedirs(folder)

    return folder


def get_img_urls(session, url):  #
    html_code = get_html(session, url)
    dom_tree = html.fromstring(html_code)
    # print(dom_tree)
    img_links = dom_tree.xpath("//article//img/@src")

    imgs = []
    for link in img_links:
        if link.startswith('https'):
            imgs.append(link)
        else:
            link = DOMAIN + link
            imgs.append(link)
    return imgs


def get_urls(session):  #
    url = 'https://site.ru/mapurls/'
    html_code = get_html(session, url)
    dom_tree = html.fromstring(html_code)
    urls = dom_tree.xpath("//table//tr//a/@href")
    # print(urls)
    return urls


def main():
    session = HTMLSession()
    urls = get_urls(session)
    for url in urls:
        folder = get_folder(session, url)
        imgs = get_img_urls(session, url)
        for img in imgs:
            name = url.split('/')[-1]
            try:
                response = session.get(img, headers=headers)
                with open(f'{folder}/{name}', 'wb') as pic:
                    pic.write(response.content)
            except Exception as e:
                print(e, type(e))


main()
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Возможно проблема в этой строке:
Python:
with open(f'{folder}/{name}', 'wb') as pic:
Если по каким-либо причинам переменные folder или name оказываются пустыми, то возникает исключение:
Код:
[Errno 13] Permission denied
Причем если folder пустой, то скрипт пытается записать картинку в файл /имя_файла.расширение_файла, то есть в корень диска C:
- этот случай решается запуском консоли от имени администратора и нормально отрабатывает,
а если обе переменные пустые, то возникает ошибка:
Код:
[Errno 13] Permission denied: '/' <class 'PermissionError'>
и запуск консоли от имени администратора не помогает, так как нет корректного пути для записи картинки.
Чтобы проверить попробуйте вместо записи в файл просто выводить в консоль значения переменных folder и name:
Python:
print(f'folder: {folder}, name: {name}')
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Возможно проблема в этой строке:
Python:
with open(f'{folder}/{name}', 'wb') as pic:
Если по каким-либо причинам переменные folder или name оказываются пустыми, то возникает исключение:
Код:
[Errno 13] Permission denied
Причем если folder пустой, то скрипт пытается записать картинку в файл /имя_файла.расширение_файла, то есть в корень диска C:
- этот случай решается запуском консоли от имени администратора и нормально отрабатывает,
а если обе переменные пустые, то возникает ошибка:
Код:
[Errno 13] Permission denied: '/' <class 'PermissionError'>
и запуск консоли от имени администратора не помогает, так как нет корректного пути для записи картинки.
Чтобы проверить попробуйте вместо записи в файл просто выводить в консоль значения переменных folder и name:
Python:
print(f'folder: {folder}, name: {name}')

Спасибо, с Вашей помощью пофиксил вариант с requests+BS, когда тайтл[0] был пустой - парсер падал. Но этот вариант с xpath так и не хочет работать, прямо с первого файла выдает Permission denied, хотя код такой же... Колдунство какое-то... Но один парсер работает) Если хотите сравнить, выложу код рабочего парсера.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Но этот вариант с xpath так и не хочет работать, прямо с первого файла выдает Permission denied
Сделайте
Python:
print(f'folder: {folder}, name: {name}')
вместо записи в файл и посмотрите есть ли там пустые значения. Так как ошибка возникает из-за них скорее всего.
 

robisho

Активный пользователь
Пользователь
Окт 19, 2020
151
26
28
Сделайте
Python:
print(f'folder: {folder}, name: {name}')
вместо записи в файл и посмотрите есть ли там пустые значения. Так как ошибка возникает из-за них скорее всего.
Вы правы, name был пустым, в main()
for img in imgs:
name = url.split('/')[-1] url надо было заменить на img

теперь все работает, спасибо за помощь.
 

Форум IT Специалистов