Làm thế nào để xóa nội dung của một thư mục?


470

Làm cách nào để xóa nội dung của thư mục cục bộ trong Python?

Dự án hiện tại là dành cho Windows, nhưng tôi cũng muốn xem * nix.


2
thành thật mà nói tôi sẽ sử dụngos.system('rm -rf folder')
Tilak Maddy

Câu trả lời:


444
import os, shutil
folder = '/path/to/folder'
for filename in os.listdir(folder):
    file_path = os.path.join(folder, filename)
    try:
        if os.path.isfile(file_path) or os.path.islink(file_path):
            os.unlink(file_path)
        elif os.path.isdir(file_path):
            shutil.rmtree(file_path)
    except Exception as e:
        print('Failed to delete %s. Reason: %s' % (file_path, e))

4
Nếu bạn đang làm việc với một thư mục rất lớn và đặc biệt là một thư mục mạng trên windows và bạn có thể kiểm soát môi trường mà chương trình này chạy, thì có thể sử dụng chức năng "os.scandir (thư mục)" của Py3.5 thay vì listdir. Cú pháp khá khác nhau sau đó, nhưng khá đơn giản để thực hiện; hạnh phúc để gửi nó nếu người khác muốn.
Michael Scott Cuthbert

Tôi đang nhận được một cảnh báo bằng cách except Exception as e:đọc W0703: Catching too general exception Exception. Có một ngoại lệ cụ thể hơn để bắt hoặc tôi nên bỏ qua nó?
John Hany

7
@JohnHany, tôi tin rằng bạn muốn bắt OSError.
MikeB

246

Bạn chỉ có thể làm điều này:

import os
import glob

files = glob.glob('/YOUR/PATH/*')
for f in files:
    os.remove(f)

Tất nhiên, bạn có thể sử dụng một bộ lọc khác trong đường dẫn của mình, ví dụ: /YOU/PATH/*.txt để xóa tất cả các tệp văn bản trong một thư mục.


12
@Blueicefield *sẽ không liệt kê các tệp bị ẩn, chúng ta cũng nên thêmglob.glob('path/.*)
satoru

5
mặc dù để xóa danh sách các tập tin, tôi có vẻ đơn giản hơn để làm:import sh; sh.rm(files)
Robin Winslow

2
Mặc dù import sh; sh.rm(files)trông đẹp hơn, bạn gặp rắc rối nếu có hơn 1024 tệp trong thư mục.
Eugene

235

Bạn có thể xóa chính thư mục đó, cũng như tất cả nội dung của nó, bằng cách sử dụng shutil.rmtree:

import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)


Xóa toàn bộ cây thư mục; đường dẫn phải trỏ đến một thư mục (nhưng không phải là một liên kết tượng trưng đến một thư mục). Nếu ign_errors là đúng, lỗi do xóa không thành công sẽ bị bỏ qua; nếu sai hoặc bị bỏ qua, các lỗi đó được xử lý bằng cách gọi một trình xử lý được chỉ định bởi onerror hoặc, nếu đó được bỏ qua, chúng sẽ đưa ra một ngoại lệ.


270
Điều này sẽ không chỉ xóa nội dung mà cả chính thư mục. Tôi không nghĩ đó là những gì câu hỏi yêu cầu.
Iker Jimenez

3
Tôi nghĩ đó là một câu trả lời tốt. Tại sao bạn không xóa nội dung và thư mục, sau đó làm lại thư mục?
cssndrx

42
Bởi vì thư mục mới và thư mục cũ sẽ không giống nhau. Vì vậy, nếu một chương trình đang ngồi trong thư mục, chờ đợi mọi thứ, nó sẽ có tấm thảm được kéo ra từ bên dưới nó.
Mike Cooper

30
Chỉ cần tạo lại thư mục sau rmtree. Giống nhưos.makedirs(dir)
Iulius Curt

3
@IuliusCurt không, tôi có một thư mục gắn trong ram Tôi cần phải có sản phẩm nào, và tiếc là tôi không thể chỉ cần xóa sau đó tái tạo lại nó:OSError: [Errno 16] Device or resource busy
Arnaud P

80

Mở rộng câu trả lời của mhawke đây là những gì tôi đã thực hiện. Nó loại bỏ tất cả nội dung của một thư mục nhưng không phải chính thư mục đó. Đã thử nghiệm trên Linux với các tệp, thư mục và các liên kết tượng trưng, ​​cũng sẽ hoạt động trên Windows.

import os
import shutil

for root, dirs, files in os.walk('/path/to/folder'):
    for f in files:
        os.unlink(os.path.join(root, f))
    for d in dirs:
        shutil.rmtree(os.path.join(root, d))

1
Tại sao "đi bộ" và không chỉ liệt kê nội dung thư mục?
Don

2
Đây là câu trả lời chính xác nếu bạn muốn xóa các thư mục là tốt. walkđược sử dụng để phân chia các thư mục so với các tệp, phải được xử lý khác nhau. Bạn cũng có thể sử dụng os.listdir, nhưng bạn phải kiểm tra xem mỗi mục nhập là một thư mục hoặc tệp theo cách thủ công.
dk vitamin

7
Điều này là gần, nhưng cả os.walk và shutil.rmtree đều được đệ quy. os.walk là không cần thiết vì bạn chỉ cần các tập tin và thư mục ở cấp cao nhất bên trong thư mục sẽ được làm sạch. Chỉ cần sử dụng một câu lệnh if trên các phần tử trong os.listdir để xem mỗi phần tử là một tệp hoặc thư mục. Sau đó sử dụng remove / unlink và rmtree tương ứng.
Matthew Alpert

1
@MatthewAlpert Lưu ý, tuy nhiên, điều đó os.walksẽ không lặp lại ở đây, bởi vì nó trả về một trình tạo, chỉ nhìn đệ quy vào các thư mục con khi bạn cố gắng tiến lên và vào thời điểm bạn thực hiện lần lặp đầu tiên của vòng lặp này, không có thư mục con nào còn lại để nhìn. Về bản chất, os.walkchỉ được sử dụng ở đây như một cách khác để phân biệt các thư mục cấp cao nhất với các tệp cấp cao nhất; đệ quy không được sử dụng và chúng tôi không phải trả chi phí thực hiện cho nó. Mặc dù vậy, nó lập dị và tôi đồng ý rằng cách tiếp cận mà bạn đề xuất là tốt hơn đơn giản vì nó rõ ràng và dễ đọc hơn.
Đánh dấu Amery

47

Sử dụng rmtreevà tạo lại thư mục có thể hoạt động, nhưng tôi đã gặp lỗi khi xóa và ngay lập tức tạo lại thư mục trên các ổ đĩa mạng.

Giải pháp được đề xuất sử dụng walk không hoạt động vì nó sử dụng rmtreeđể xóa các thư mục và sau đó có thể cố gắng sử dụng os.unlinktrên các tệp trước đó trong các thư mục đó. Điều này gây ra lỗi.

globGiải pháp được đăng cũng sẽ cố gắng xóa các thư mục không trống, gây ra lỗi.

Tôi đề nghị bạn sử dụng:

folder_path = '/path/to/folder'
for file_object in os.listdir(folder_path):
    file_object_path = os.path.join(folder_path, file_object)
    if os.path.isfile(file_object_path) or os.path.islink(file_object_path):
        os.unlink(file_object_path)
    else:
        shutil.rmtree(file_object_path)

1
Giải pháp của bạn cũng sẽ phát sinh lỗi nếu có một liên kết tượng trưng đến một thư mục khác.
Blueicefield

@Blueicefield - Bạn có thể cung cấp một ví dụ. Tôi đã kiểm tra linux bằng tệp và thư mục được liên kết và chưa thể gây ra lỗi.
jgoeders

@jgoeders - Nếu có một liên kết tượng trưng đến một thư mục, os.path.isfile()sẽ trả về False(vì nó theo liên kết tượng trưng) và cuối cùng bạn sẽ gọi shutil.rmtree()trên một liên kết tượng trưng, ​​sẽ tăng lên OSError("Cannot call rmtree on a symbolic link").
Rockallite

1
@Rockallite cố định bằng séc để islink
kevinf

1
Ngoài ra: @kevinf là chính xác để chỉ ra sự cần thiết phải islinkkiểm tra ở đây để xử lý các liên kết tượng trưng đến các thư mục một cách chính xác. Tôi đã thêm một kiểm tra như vậy vào câu trả lời được chấp nhận.
Đánh dấu Amery

20

Điều này:

  • xóa tất cả các liên kết tượng trưng
    • liên kết chết
    • liên kết đến thư mục
    • liên kết đến tập tin
  • xóa thư mục con
  • không xóa thư mục mẹ

Mã số:

for filename in os.listdir(dirpath):
    filepath = os.path.join(dirpath, filename)
    try:
        shutil.rmtree(filepath)
    except OSError:
        os.remove(filepath)

Như nhiều câu trả lời khác, điều này không cố gắng điều chỉnh quyền để cho phép loại bỏ các tập tin / thư mục.


15

Là một oneliner:

import os

# Python 2.7
map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )

# Python 3+
list( map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) ) )

Một giải pháp mạnh mẽ hơn kế toán cho các tập tin và thư mục cũng sẽ là (2.7):

def rm(f):
    if os.path.isdir(f): return os.rmdir(f)
    if os.path.isfile(f): return os.unlink(f)
    raise TypeError, 'must be either file or directory'

map( rm, (os.path.join( mydir,f) for f in os.listdir(mydir)) )

1
đối với các hoạt động lớn sử dụng trình tạo có thể hiệu quả hơn một chútmap( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
user25064

Thực sự đang cố gắng sử dụng điều này, nhận ra đối tượng bản đồ phải được lặp đi lặp lại nên một cuộc gọi đến danh sách (hoặc thứ gì đó sẽ lặp lại) được yêu cầu nhưlist(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
user25064

Cái đầu tiên bao gồm trong câu trả lời, cái thứ hai không có ý nghĩa với tôi. Tại sao bạn nên lặp lại một chức năng được ánh xạ tới một lần lặp? Bản đồ làm điều đó.
fmonegaglia

1
Trong Python3, bạn phải quấn maptrong list để thực sự lặp. Xem http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-x
paulwasit

Cái này chắc chắn sẽ không hoạt động nếu 'mydir' chứa ít nhất một thư mục, vì unlink chỉ hoạt động cho các tệp ...
kupsef

14

Ghi chú: trong trường hợp ai đó bình chọn câu trả lời của tôi, tôi có vài điều cần giải thích ở đây.

  1. Mọi người đều thích những câu trả lời đơn giản ngắn gọn. Tuy nhiên, đôi khi thực tế không đơn giản như vậy.
  2. Quay lại câu trả lời của tôi. Tôi biết shutil.rmtree()có thể được sử dụng để xóa một cây thư mục. Tôi đã sử dụng nó nhiều lần trong các dự án của riêng tôi. Nhưng bạn phải nhận ra rằng chính thư mục cũng sẽ bị xóa bởishutil.rmtree() . Mặc dù điều này có thể được chấp nhận đối với một số người, nhưng đây không phải là câu trả lời hợp lệ để xóa nội dung của thư mục (không có tác dụng phụ) .
  3. Tôi sẽ chỉ cho bạn một ví dụ về các tác dụng phụ. Giả sử rằng bạn có một thư mục với các bit chế độ và chủ sở hữu tùy chỉnh , nơi có rất nhiều nội dung. Sau đó, bạn xóa nó với shutil.rmtree()và xây dựng lại với os.mkdir(). Và bạn sẽ nhận được một thư mục trống với các bit chế độ và chủ sở hữu mặc định (được kế thừa). Mặc dù bạn có thể có đặc quyền xóa nội dung và thậm chí cả thư mục, bạn có thể không thể đặt lại chủ sở hữu ban đầu và các bit chế độ trên thư mục (ví dụ: bạn không phải là siêu người dùng).
  4. Cuối cùng, hãy kiên nhẫn và đọc mã . Nó dài và xấu (trong tầm nhìn), nhưng được chứng minh là đáng tin cậy và hiệu quả (đang sử dụng).

Đây là một giải pháp dài và xấu, nhưng đáng tin cậy và hiệu quả.

Nó giải quyết một vài vấn đề không được giải đáp bởi những người trả lời khác:

  • Nó xử lý chính xác các liên kết tượng trưng, ​​bao gồm cả việc không gọi shutil.rmtree()vào một liên kết tượng trưng (sẽ vượt qua os.path.isdir()bài kiểm tra nếu nó liên kết đến một thư mục; thậm chí kết quả của việc os.walk()chứa các thư mục được liên kết tượng trưng là tốt).
  • Nó xử lý các tập tin chỉ đọc độc đáo.

Đây là mã (chức năng hữu ích duy nhất là clear_dir()):

import os
import stat
import shutil


# http://stackoverflow.com/questions/1889597/deleting-directory-in-python
def _remove_readonly(fn, path_, excinfo):
    # Handle read-only files and directories
    if fn is os.rmdir:
        os.chmod(path_, stat.S_IWRITE)
        os.rmdir(path_)
    elif fn is os.remove:
        os.lchmod(path_, stat.S_IWRITE)
        os.remove(path_)


def force_remove_file_or_symlink(path_):
    try:
        os.remove(path_)
    except OSError:
        os.lchmod(path_, stat.S_IWRITE)
        os.remove(path_)


# Code from shutil.rmtree()
def is_regular_dir(path_):
    try:
        mode = os.lstat(path_).st_mode
    except os.error:
        mode = 0
    return stat.S_ISDIR(mode)


def clear_dir(path_):
    if is_regular_dir(path_):
        # Given path is a directory, clear its content
        for name in os.listdir(path_):
            fullpath = os.path.join(path_, name)
            if is_regular_dir(fullpath):
                shutil.rmtree(fullpath, onerror=_remove_readonly)
            else:
                force_remove_file_or_symlink(fullpath)
    else:
        # Given path is a file or a symlink.
        # Raise an exception here to avoid accidentally clearing the content
        # of a symbolic linked directory.
        raise OSError("Cannot call clear_dir() on a symbolic link")

Tôi không hiểu bối cảnh thay đổi chế độ tập tin có ý nghĩa gì. Trên máy Mac của tôi, os.remove, không giống như các rmtiện ích, là hạnh phúc để xóa read-only file miễn là bạn sở hữu chúng. Trong khi đó, nếu đó là một tệp bạn không sở hữu mà bạn chỉ có quyền truy cập chỉ đọc, thì bạn không thể xóa nó hoặc thay đổi quyền của nó. Tôi không biết bất kỳ tình huống nào trên bất kỳ hệ thống nào mà bạn không thể xóa tệp chỉ đọc os.removemà vẫn có thể thay đổi quyền của nó. Hơn nữa, bạn sử dụng lchmod, không tồn tại trên máy Mac của tôi, cũng như trên Windows theo tài liệu của nó. Mã này dùng để làm gì?
Đánh dấu Amery

14

Tôi ngạc nhiên không ai đã đề cập đến sự tuyệt vời pathlibđể làm công việc này.

Nếu bạn chỉ muốn xóa các tập tin trong một thư mục, nó có thể là một oneliner

from pathlib import Path

[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()] 

Để xóa đệ quy các thư mục, bạn có thể viết một cái gì đó như thế này:

from pathlib import Path
from shutil import rmtree

for path in Path("/path/to/folder").glob("**/*"):
    if path.is_file():
        path.unlink()
    elif path.is_dir():
        rmtree(path)

1
.iterdir()thay vì .glob(...)cũng nên làm việc
S. Kirby

12
import os
import shutil

# Gather directory contents
contents = [os.path.join(target_dir, i) for i in os.listdir(target_dir)]

# Iterate and remove each item in the appropriate manner
[os.remove(i) if os.path.isfile(i) or os.path.islink(i) else shutil.rmtree(i) for i in contents]

Một nhận xét trước đó cũng đề cập đến việc sử dụng os.scandir trong Python 3.5+. Ví dụ:

import os
import shutil

with os.scandir(target_dir) as entries:
    for entry in entries:
        if entry.is_file() or entry.is_symlink():
            os.remove(entry.path)
        elif entry.is_dir():
            shutil.rmtree(entry.path)

1
os.path.isdir()không phải là một cách hợp lệ để phân biệt giữa một thư mục thông thường và một liên kết tượng trưng. Gọi shutil.rmtree()một liên kết tượng trưng sẽ đưa ra OSErrorngoại lệ.
Rockallite

@Rockallite Cảm ơn. Bạn đúng. Tôi đã cập nhật ví dụ.
Jacob Wan

8

Bạn có thể tốt hơn sử dụng os.walk()cho việc này.

os.listdir()không phân biệt các tệp từ các thư mục và bạn sẽ nhanh chóng gặp rắc rối khi cố gắng hủy liên kết các tệp này. Có một ví dụ điển hình về việc sử dụng os.walk()để loại bỏ đệ quy một thư mục ở đây và gợi ý về cách điều chỉnh nó phù hợp với hoàn cảnh của bạn.


6

Tôi đã sử dụng để giải quyết vấn đề theo cách này:

import shutil
import os

shutil.rmtree(dirpath)
os.mkdir(dirpath)

7
Điều này có ý nghĩa hoàn toàn khác với những gì câu hỏi yêu cầu và không nên được coi là một câu trả lời hợp lệ.
fatuhoku

1
Với sự tôn trọng tôi nghĩ rằng "Xóa nội dung của thư mục cục bộ" không liên quan đến việc xóa chính thư mục đó. Vấn đề tương tự như câu trả lời này , ngoại trừ việc người ta nhận được rất nhiều sự ủng hộ!
fatuhoku

3
Nó giống như trả lời câu hỏi "Làm thế nào để tôi có hàm trả về số 1 trong Python?" với def return_a_one (): launch_some_nukes () return 1
fatuhoku

2
Tất nhiên ngữ nghĩa là khác nhau: Nhưng bạn cũng có thể coi nó như một cách khác để xem xét vấn đề. Giải pháp này là hoàn toàn hợp lệ vì nó giải quyết vấn đề. Có một sự khác biệt với ví dụ 'launch_some_nukes của bạn: 1. Giải pháp ngắn hơn và dễ dàng hơn so với giải pháp được chấp nhận và trái ngược với câu trả lời bạn trích dẫn là hợp lệ. 2. tương đương 'launch_some_nukes' trong trường hợp này là xóa và tạo lại một thư mục. Sự khác biệt giữa thư mục cũ và thư mục mới chỉ là số inode (có thể không liên quan đến OP)
ProfHase85

2
Nó khá là phá hủy tòa nhà chọc trời và xây dựng lại một kích thước chính xác như nhau;)
ProfHase85

5

Một giải pháp khác:

import sh
sh.rm(sh.glob('/path/to/folder/*'))

1
Lưu ý rằng đó shkhông phải là một phần của thư viện chuẩn và cần cài đặt từ PyPI trước khi bạn có thể sử dụng nó. Ngoài ra, vì điều này thực sự gọi rmtrong một quy trình con, nó sẽ không hoạt động trên Windows khi rmkhông tồn tại. Nó cũng sẽ đưa ra một ngoại lệ nếu thư mục chứa bất kỳ thư mục con nào.
Đánh dấu Amery

5

Tôi không biết đó là một chủ đề cũ nhưng tôi đã tìm thấy một điều thú vị từ trang web chính thức của trăn. Chỉ để chia sẻ một ý tưởng khác để loại bỏ tất cả nội dung trong một thư mục. Bởi vì tôi có một số vấn đề về ủy quyền khi sử dụng shutil.rmtree () và tôi không muốn xóa thư mục và tạo lại nó. Địa chỉ ban đầu là http://docs.python.org/2/l Library / os.html # os.walk . Hy vọng rằng có thể giúp đỡ một ai đó.

def emptydir(top):
    if(top == '/' or top == "\\"): return
    else:
        for root, dirs, files in os.walk(top, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

4

Để xóa tất cả các tệp bên trong thư mục cũng như các thư mục con của nó, mà không cần tự xóa các thư mục, chỉ cần làm điều này:

import os
mypath = "my_folder" #Enter your path here
for root, dirs, files in os.walk(mypath):
    for file in files:
        os.remove(os.path.join(root, file))

3

Nếu bạn đang sử dụng hệ thống * nix, tại sao không tận dụng lệnh hệ thống?

import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)

3
Bởi vì, như đã nêu trong câu hỏi, "Dự án hiện tại dành cho Windows"
sox với Monica

3

Cách làm khá trực quan:

import shutil, os


def remove_folder_contents(path):
    shutil.rmtree(path)
    os.makedirs(path)


remove_folder_contents('/path/to/folder')

3

Vâng, tôi nghĩ rằng mã này đang hoạt động. Nó sẽ không xóa thư mục và bạn có thể sử dụng mã này để xóa các tệp có phần mở rộng cụ thể.

import os
import glob

files = glob.glob(r'path/*')
for items in files:
    os.remove(items)

3

Tôi đã phải xóa các tệp khỏi 3 thư mục riêng biệt trong một thư mục cha mẹ:

directory
   folderA
      file1
   folderB
      file2
   folderC
      file3

Mã đơn giản này đã lừa tôi: (Tôi đang dùng Unix)

import os
import glob

folders = glob.glob('./path/to/parentdir/*')
for fo in folders:
  file = glob.glob(f'{fo}/*')
  for f in file:
    os.remove(f)

Hi vọng điêu nay co ich.


1

Tôi đã giải quyết vấn đề bằng rmtree makedirscách thêm vào time.sleep()giữa:

if os.path.isdir(folder_location):
    shutil.rmtree(folder_location)

time.sleep(.5)

os.makedirs(folder_location, 0o777)

0

Trả lời cho một tình huống cụ thể, hạn chế: giả sử bạn muốn xóa các tệp trong khi duy trì cây thư mục con, bạn có thể sử dụng thuật toán đệ quy:

import os

def recursively_remove_files(f):
    if os.path.isfile(f):
        os.unlink(f)
    elif os.path.isdir(f):
        for fi in os.listdir(f):
            recursively_remove_files(os.path.join(f, fi))

recursively_remove_files(my_directory)

Có thể hơi lạc đề, nhưng tôi nghĩ nhiều người sẽ thấy nó hữu ích


Sử dụng os.walktheo cách hiển thị tại stackoverflow.com/a/54889532/1709587 có lẽ là một cách tốt hơn để xóa tất cả các tệp trong khi vẫn giữ nguyên cấu trúc thư mục.
Đánh dấu Amery

-1

Giả sử temp_dirbị xóa, một dòng lệnh sử dụng ossẽ là:

_ = [os.remove(os.path.join(save_dir,i)) for i in os.listdir(temp_dir)]

Lưu ý: Đây chỉ là phần 1 để xóa các tệp 'Không xóa các thư mục.

Hi vọng điêu nay co ich. Cảm ơn.


-1

Sử dụng phương thức dưới đây để xóa nội dung của một thư mục, không phải chính thư mục đó:

import os
import shutil

def remove_contents(path):
    for c in os.listdir(path):
        full_path = os.path.join(path, c)
        if os.path.isfile(full_path):
            os.remove(full_path)
        else:
            shutil.rmtree(full_path)

@FabioSpaghetti phủ định
Amir Rezazadeh

cảm ơn Amir, tôi đang tìm kiếm một giải pháp tìm thấy một thư mục nhất định trong tất cả các thư mục con của thư mục gốc và xóa nội dung của thư mục đó
FabioSpaghetti

Điều này cho biết thêm không có gì mới chưa được hiển thị trong câu trả lời được chấp nhận nhiều năm trước khi bạn đăng bài này.
Đánh dấu Amery

-1

cách dễ nhất để xóa tất cả các tệp trong một thư mục / xóa tất cả các tệp

import os
files = os.listdir(yourFilePath)
for f in files:
    os.remove(yourFilePath + f)

Thất bại nếu có thư mục con.
Đánh dấu Amery

-3

Điều này nên thực hiện thủ thuật chỉ cần sử dụng mô-đun hệ điều hành để liệt kê và sau đó loại bỏ!

import os
DIR = os.list('Folder')
for i in range(len(DIR)):
    os.remove('Folder'+chr(92)+i)

Làm việc cho tôi, bất kỳ vấn đề cho tôi biết!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.