01/10/2018, 11:08

Hỏi về vấn đề xử lý tiếng Việt với Python

Em đang viết 1 chương trình crawl dữ liệu về insert vào database nhưng em đang gặp vấn đề như sau ạ:

Khi dữ liệu crawl về em xử lý qua hàm sau thì chạy tốt

import unicodedata
def formatText(self,text):
return unicodedata.normalize(‘NFKD’, text).encode(‘ascii’,‘ignore’)

Nhưng vấn đề là hàm trên làm mất đi dấu tiếng việt của text.
Em sửa hàm trên lại thành như bên dưới thì k mất đi dấu Tiếng Việt nhưng lại không chèn vào câu lệnh SQL dc.

import unicodedata
def formatText(self,text):
return unicodedata.normalize(‘NFKD’, text) #bỏ đi cái encode ở cuối

Khi sửa lại như thế này thì lúc tạo câu lệnh SQL và print ra thử thì bị báo lỗi như sau ạ

print sql
File “c:python27libencodingscp1258.py”, line 12, in encode
return codecs.charmap_encode(input,errors,encoding_table)
UnicodeEncodeError: ‘charmap’ codec can’t encode character u’u031b’ in position 81: character maps to

“Nhiều lúc em nghĩ em đã làm sai điều gì, mà code cứ ỳ không chịu chạy tí chi”

Mong các bác giúp em

Dark.Hades viết 13:11 ngày 01/10/2018

DB bạn là UTF-8 hay ASCII?
Mặc định UTF-8 rồi thì cứ để bình thường thôi chứ mất công encode nữa làm gì

D@dpool viết 13:23 ngày 01/10/2018

Print trên command line bác chạy câu lệnh chcp 65001 r print lại nhé

Hà Temwin viết 13:09 ngày 01/10/2018

DB của em là UTF-8 nhưng vấn đề là nếu em không có hàm encode ấy thì không thể viết câu lệnh SQL dc.
Bác giúp em với!

Hà Temwin viết 13:11 ngày 01/10/2018

các bác giúp em với :((

Thành Phạm viết 13:11 ngày 01/10/2018

Bạn up hết code lên xem, đặc biệt là phần SQL

không thể viết câu lệnh SQL

Nghĩa là như nào? Có thông báo lỗi gì khi execute sql k?

Hà Temwin viết 13:09 ngày 01/10/2018
def process_item(self, item, spider):
    sql = """INSERT INTO crawlspider SET
               `name` = '""" + item['name'] + """', 
               `link` = '""" + item['url'] + """',
               `description` = '""" + item['price'] + """',
               `img` = 'day la img nhe'"""
    #print sql
    try:
        # Execute the SQL command
        self.cursor.execute(sql)
        # Commit your changes in the database
        self.db.commit()
    except:
        # Rollback in case there is any error
        self.db.rollback()
   
    return item

Đây là đoạn code SQL.Câu lệnh SQL ở đây không được tạo vì có thể là do kiểu dữ liệu của biến item nên không thể cộng (+) các string với nhau được.

Biến em lấy về được và ghi vào file nó có dạng như thế này ạ

[
{
“price”: “281.800”,
“name”: "\n \u0110\u1ed3ng h\u1ed3 nam WWOOR 8018 m\u00e1y m\u1ecfng (\u0110en) \u00a0\n ",
}
]

Henry viết 13:10 ngày 01/10/2018

Cho hỏi là trước khi ghi vào file nó đã bị biến thành mấy cái chữ lằng ngoằng này chưa? Nếu rồi thì bạn decode utf-8 nó (Tùy theo cái encode của bạn trong SQL). Mở file thì bạn mở file nhớ thêm một parameter như thế này

open(file_name, 'w', encoding='utf-8')
Hà Temwin viết 13:09 ngày 01/10/2018

tf-8 nó (Tùy theo cái encode của bạn trong SQL

Trước khi vào file nó thế này rồi bác ạ.

Bác cho em xin lênh decode UTF-8 nó trước khi ghi vào file được không ạ?
Mục đích cuối cùng của em k phải là vào file mà là vào database

Henry viết 13:22 ngày 01/10/2018

nó là string. Đơn giản thôi

string.decode('utf-8')
Thành Phạm viết 13:22 ngày 01/10/2018

def process_item(self, item, spider):

sql = """INSERT INTO crawlspider SET
           `name` = '""" + item['name'] + """', 
           `link` = '""" + item['url'] + """',
           `description` = '""" + item['price'] + """',
           `img` = 'day la img nhe'"""
#print sql

try:
    # Execute the SQL command
    self.cursor.execute(sql)
    # Commit your changes in the database
    self.db.commit()
except:
    # Rollback in case there is any error
    self.db.rollback()

return item

Đây là đoạn code SQL.Câu lệnh SQL ở đây không được tạo vì có thể là do kiểu dữ liệu của biến item nên không thể cộng (+) các string với nhau được.

Biến em lấy về được và ghi vào file nó có dạng như thế này ạ

[
{
“price”: “281.800”,
“name”: "\n \u0110\u1ed3ng h\u1ed3 nam WWOOR 8018 m\u00e1y m\u1ecfng (\u0110en) \u00a0\n ",
}
]

Bạn chạy đoạn code trên (đoạn code đã comment dòng print sql) xong tiếp ra thông báo lỗi là gì? Bởi vì khi bạn comment dòng print sql rồi thì sẽ không còn lỗi UnicodeEncodeError nữa, vậy lỗi tiếp theo là gì?

Hà Temwin viết 13:16 ngày 01/10/2018

UnicodeEncodeError: ‘charmap’ codec can’t encode character u’\u1ea6’

Em chạy như trên và bị lỗi này ạ

Dark.Hades viết 13:16 ngày 01/10/2018

Bạn đang thực hiện encode hay decode?
Nhìn code của bạn thì ban đầu bạn thực hiện crawl, sau nhận đc dữ liệu thì bạn encode sang cp1258(đúng ascii phải là 1252) sau đó lại thực hiện chuyển sang utf-8. Không hiểu phức tạp hoá lên làm gì?

Dữ liệu bạn crawl về không nhầm thì là json, trong json khi encode nó tự động chuyển dữ liệu về ascii, việc bạn cần làm là decode json chứ không phải decode code page của json

Bạn thử crawl đc dữ liệu rồi thực hiện decode json, sau đó ghi vào file xem nó bị gì ko

Hà Temwin viết 13:23 ngày 01/10/2018

Em muốn thực hiện decode, vì cái dữ liệu em crawl về print ra nó như thế này mà ghi vào file nó cũng như thế này luôn

“name”: "\n \u0110\u1ed3ng h\u1ed3 nam WWOOR 8018 m\u00e1y m\u1ecfng (\u0110en) \u00a0\n ",

Dark.Hades viết 13:14 ngày 01/10/2018

Bạn tìm hiểu về json decode trong python, đây là một kiểu mã hoá dữ liệu thường thấy trong lập trình( đa số là api của web ).
Json sau khi decode sử dụng y hệt array

Ref:
https://docs.python.org/3/library/json.html

print(json.loads(crawled data variable))

Hà Temwin viết 13:24 ngày 01/10/2018

Em tóm gọn lại vấn đề như thế này nhờ bác giúp em 1 câu lệnh ạ.

Đây là chuỗi ký tự em crawl về được

str = u’\r\n \u0110\u1ea6M X\xd2E HOA MYLAN TR\u1eba TRUNG BEYEU1688 - BY3177\xa0\r\n’

Tên đầy đủ của nó là (và đây là kết quả em muốn in ra)

ĐẦM XÒE HOA MYLAN TRẺ TRUNG BEYEU1688 - BY3177

Em sử dụng đoạn code sau

import unicodedata
print unicodedata.normalize(‘NFKD’, str).encode(‘ascii’,‘ignore’)

Nhưng kết quả lại bị mất dấu Tiếng Việt

AM XOE HOA MYLAN TRE TRUNG BEYEU1688 - BY3177

Em muốn thực hiện đoạn code trên mà vẫn giữ được dấu Tiếng Việt thì phải làm thế nào ạ?
(Em phải sử dụng hàm đấy thì em mới lấy kết quả để INSERT vào database được)

Mong bác chỉ giáo cho ạ

Dark.Hades viết 13:24 ngày 01/10/2018

Unikey error…

You must understand what you trying to do and what you are writing.
In your code, you use u'', that means python will auto decode it to unicode for you.

wandbox.org

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

# This file is a "Hello, world!" in Python language by CPython for wandbox. str = u'\r\n \u0110\u1ea6M X\xd2E HOA MYLAN TR\u1eba TRUNG BEYEU1688 - BY3177\xa0\r\n' print(str) # CPython references: #

Hà Temwin viết 13:25 ngày 01/10/2018

vậy đơn giản nhất là bỏ cái u’ ’ thì làm như thế nào ạ?
Vì trong khi tạo câu lệnh SQL nó không chấp nhận biến u’ ’

viết 13:21 ngày 01/10/2018

Python3 làm gì còn u’’, string trong python 3 mặc định là Unicode luôn rồi thì phải

khi thêm vào thì xài str.encode('utf-8'), khi lấy ra thì str.decode('utf-8')

sql = """INSERT INTO crawlspider SET
           `name` = '""" + item['name'].encode('utf-8') + """', 
           `link` = '""" + item['url'].encode('utf-8') + """',
           `description` = '""" + item['price'].encode('utf-8') + """',
           `img` = 'day la img nhe'"""
#print sql

mà cái sql vậy lỡ có ai inject mã độc thì bay luôn cái table, dữ liệu crawl được ko biết có an toàn ko

Hà Temwin viết 13:23 ngày 01/10/2018

Em đã thử str.encode(‘utf-8’) nhưng khi vào database thì nó lại bị mất dấu tiếng việt. Kết quả vào databse là nó như này

            ĐẦM XÒE HOA MYLAN TRẺ TRUNG BEYEU1688 - BY3177                 

Mà SQL của em có vấn đề gì hả bác? Nên làm thế nào thì mới ổn?

Bài liên quan
0