Tối qua tự nhiên có hứng thú làm cái công việc trích xuất danh sách bài hát Karaoke 5 số để lưu trữ nhằm phục vụ vào mục đích khác.
Nếu bạn nào có đi hát Karaoke (mình cũng khoái dzụ này lắm) thì cũng biết hiện nay các đầu Karaoke thường là của Arirang 5 số. Và vô đó muốn hát thì chọn số từ mấy cuốn songlist.
Tự nhiên thèm có 1 website để tra cứu cho nhanh hoặc tốt nhất là có hẳn 1 cái Database để tự mình triển khai, có thể dùng cho web, software cho máy tính, di động..đồng thời không muốn lệ thuộc vào các software khác (nghe nói cũng có cái soft nào đó rồi và có cả iphone app) nên đành nghiên cứu thử xem có thể “tự thân vận động” không!
Thế là sau 2 tiếng ngáp lên ngáp xuống (1h-3h sáng) vừa nghiên cứu vừa code thì cũng đã được như ý. Mình đã lấy được danh sách bài hát 5 số của Arirang, gồm có Danh sách tiếng việt (tới Vol 37) và tiếng anh. Nội dung bài viết này mình sẽ hướng dẫn các bạn(Programmer) làm sao có thể trích xuất được danh sách bài hát ra định dạng mà mình muốn, đồng thời cũng chia sẽ tới các bạn luôn Database MySQL mà mình đã trích xuất được coi như 1 món quà đầu năm dành cho các Programmer.
Nếu muốn download thì có thể bỏ qua phần hướng dẫn này và kéo xuống phần download để tải về Database (MySQL) và file HTML (chứa danh sách bài hát tiếng Việt + tiếng Anh) để dùng trình duyệt tra cứu cũng được ^^. Còn nếu ai muốn export dạng nào khác thì có thể nói mình, giúp được mình sẽ giúp. Khi sử dụng Database thì các bạn có thể ghi chút nguồn gốc là từ bloghoctap thì mình vui rồi.
A.Hướng dẫn trích xuất danh sách bài hát Karaoke 5 số
Không dành cho người yếu tim và người mới bắt đầu code :D!
Mình sẽ hướng dẫn các bạn 1 số bước quan trong mà mình đã thực hiện để trích xuất được danh sách bài hát Karaoke 5 số. Nói đến quá trình này trước tiên cũng nhắc cho các bạn biến là đối với danh sách tiếng Việt và tiếng Anh thì mình sẽ làm hầu như là khác nhau. Cách Convert, Export, Viết Script PHP. Ở đây mình tất nhiên sẽ không hướng dẫn chi tiết các đoạn script PHP của mình mà mình chỉ share một số đoạn quan trọng mà thôi, hy vọng các bạn làm theo các bước mình chỉ để thực tập. Và cũng nói với các bạn biết là bước code PHP rất đơn giản, khó là công đoạn đầu chuẩn bị đầu vào cho file PHP xử lý thôi. Nào bắt đầu!
Đầu tiên bạn phải cần có File chứa danh sách bài hát để bắt đầu “thực tập”, vì nó ở định dạng PDF nên mình mới phải vất vả tùm lum việc để extract nó ra Database thành công. Bạn chỉ cần vào địa chỉ http://arirang.com.vn/?page=static_pages&view=99&l=2 để tải về file PDF mà mình cần tiến hành export. Vì thực tế mình biết là chúng ta chỉ cần quan tâm List nhạc Việt và List nhạc tiếng Anh (Chỉ cần file phần “Danh mục bài hát tiếng Anh dành cho 3600 HI“, mấy cái khác hình như không phải vì không phải bắt đầu bằng số 4 ^^). Download về và tiếp tục nhé.
Cái khó nhất của project này là làm sao bạn convert file PDF sang một định dạng nào đó mà có pattern (có khuôn mẫu giống nhau đối với các bài hát) để từ đó các bạn có thể dùng các ngôn ngữ lập trình mà các bạn thông thạo (đối với mình là PHP) tiến hành đọc chuỗi, tách và tìm đúng thông tin cần extract là sẽ thành công.
1. Trích xuất bài hát tiếng Việt:
Tới thời điểm bài viết này thì đã có tới Vol 37 (Vol này chả biết hát bài nào hết trơn ^^) nên nhiệm vụ của chúng ta sẽ là extract được tất cả bài hát từ Vol 1 – 37.
Bước 1:Convert từ PDF –> TXT
Vì định dạng ban đầu là PDF nên không cách chi PHP đọc được vì nó không có pattern nên phải tiến hành biến nó thành file text để PHP có thể đọc được. Lúc đầu tưởng công việc cực khổ lắm ai dè giải quyết rất đơn giản ^^. Nếu bạn đang sử dụng Adobe Reader 9 thì có thể vào File >> Save as text là đã có file TXT có pattern rồi.
Sau khi convert bạn sẽ có File TXT có nội dung giống như sau:
Bạn sẽ thực hiện bước export ra text đối với các file PDF chứa vol 1-35, vol36,vol37, sau đó copy tất cả vào 1 file để dễ làm việc. Như vậy là bạn đã có toàn bộ bài hát từ Vol1-37 ở định dạng text.
Bước 2: Như bạn thấy thì file mình convert ra sẽ bị lỗi dấu tiếng việt bởi vì nó đang được encoding VNI. Bạn cần phải chuyển nó sang Unicode trước khi chuyển giao qua bước cuối cùng. Để chuyển thì cực kỳ đơn giản, sử dụng công cụ convert của Unikey chỉ vài giây là xong. Mở file text ở bước 1 bằng Notepad, đầu tiên bạn Cut toàn bộ nội dung text, sử dụng Unikey Toolkit(nằm ở menu công cụ của Unikey) và thiết lập như hình mình chụp dưới đây, sau đó nhấn chuyển mã và chương trình sẽ báo thành công. Bạn quay lại Notepad và Paste vô thì sẽ thấy tiếng Việt thôi. Sau đó Save as với định dạng Unicode nha.
Bước 3: tới đây coi như bạn đã có File text có tiếng việt và có pattern để có thể sử dụng ngôn ngữ lập trình mà mình quen thuộc và đọc ra thôi. Mình cũng chia sẽ với ai dự định Coding. Nếu các bạn để ý, File của chúng ta sẽ có dạng mỗi thông tin nằm trên 1 hàng, và một bài hát bắt đầu bằng hàng có 5 chữ số, hàng tiếp theo là tên bài hát, hàng tiếp theo nữa là 1 đoạn lyric và có thể 1,2..hàng tiếp theo là tác giả. Biết được Pattern thì các bạn có thể coding để lấy thông tin mà mình muốn nhé. Sau khi đọc được thì các bạn có thể lưu vào database hay làm gì đó thì tùy.Vậy là xong tiếng Việt.
Dưới đây là 1 phần trong đoạn script của mình đã viết, nhiệm vụ của nó là parse 1 bài hát và lấy các thông tin từ bài hát đó (code,title,lyric,composer).
/**
* Ham parsing data tu 1 bai hat
*
* @param string $song
*/
function parseSong($song)
{
$songData = array('code' => '', 'title' => '', 'lyric' => '', 'composer' => '');
$songPart = split("\n", trim($song));
$songRawData = array();
foreach($songPart as $part)
{
$part = trim($part);
if(strlen($part) > 0)
$songRawData[] = $part;
}
if(is_numeric($songRawData[0]) && strlen($songRawData[0]) == 5)
{
$songData['code'] = $songRawData[0];
$songData['title'] = $songRawData[1];
$songData['lyric'] = $songRawData[2];
for($i = 3; $i < count($songRawData); $i++)
{
if(strlen($songRawData[$i]) > 5 && strpos($songRawData[$i], 'www') === false && $songRawData[$i] != $songRawData[$i-1])
$songData['composer'] .= $songRawData[$i] . "\n";
else
break;
}
$songData['composer'] = trim($songData['composer']);
}
return $songData;
}
2. Trích xuất bài hát tiếng Anh:
Bước 1:Thật sự lúc đầu tưởng làm xong tiếng Việt thì tiếng Anh cũng dễ vì cứ nghĩ nó giống nhau, nhưng mình đã sai lầm. Mọi người đi hát Karaoke cũng thấy cái songlist của tiếng anh nó khác mà đúng không, mình thử lập lại bước 1 ở trên bằng cách dùng Adobe Reader 9 để export ra txt nhưng kết quả đã khiến mình thất vọng.
Nhìn cái file TXT mà đau cả lòng vì nó không có pattern để parsing bài hát, chỉ biết là mỗi bài trên 1 dòng, nhưng trong 1 dòng thì lại khó mà biết đâu là Title, đâu là Singer :(. Thế là tìm giải pháp khác.
Mình nghĩ tới phải export cái này qua excel thì may ra vì excel gần với PHP hơn. Search thử thì ra software “PDF to Excel Converter 2.2”, hy vọng nó giúp mình. Đây là 1 shareware, tuy nhiên xài thử thì nó export ra được đầy đủ file XLS, vậy là xong bước 1.
Bước 2: Sau khi có file XLS mở ra và xóa các dòng và cột không cần thiết đi và export sang CSV (PHP parsing CSV sướng hơn chứ ^^) thì thấy có pattern rồi thế là tha hồ lấy PHP mà parsing. Nhưng…:D, cái bạn export từ file excel ra CSV chỉ là export mới có 1 sheet, nhưng file excel của mình có tới 74 Sheet(do file PDF có 74 trang), thế là lại bắt đầu 1 bài toán mới, bài toán làm sao merge tất cả sheet và export ra 1 file duy nhất. Để giải quyết bài toán nan giải này có 2 cách:
+ Cách đầu tiên nhanh lẹ gọn là sử dụng 1 cái software tên là “Merge Excel Sheets v2.9“, cái này phải mua mới xài được, còn bạn nào giỏi thì có thể xài “thuốc”, không lẽ nào mình lại đưa “thuốc” lên đây, như thế không tốt. Dùng software này nó sẽ merge 1 file có nhiều worksheet lại thành 1 file chỉ có 1 worksheet và chứa toàn bộ các worksheet của file excel gốc. Sau khi có file mới này rồi thì có thể export ra CSV bình thường như đầu tiên thì sẽ có tất cả dữ liệu rồi.
+ Cách này sử dụng hơi “technical” một tý nhưng được cái học hỏi được nhiều mà lại miễn phí, đó là sử dụng cơ chế Macro của Excel để hỗ trợ mình. Bạn cần tạo 2 Macro, 1 Macro cho phép export tất cả worksheet thành mỗi file CSV riêng và đặt ở đâu đó (mình mặc định là ở ổ C, bạn có thể nghiên cứu Macro để thiết đặt lại) và 1 Macro cho Merge tất cả file CSV vừa export ra thành 1 file CSV duy nhất. Mình chỉ sơ qua cách tạo 1 Macro: Nhấn Alt+F11 nó sẽ mở cửa sổ Visual Basic, vào Insert >> Module và copy nội dung của Macro. Bạn thực hiện việc tạo này cho 2 Macro có nội dung dưới đây:
.Macro (ExportSheetToCSV) export các worksheet của Excel thành các file CSV tương ứng:
Option Explicit
Sub ExportSheetToCSV()
Dim newWks As Worksheet
Dim wks As Worksheet
For Each wks In ActiveWorkbook.Worksheets
wks.Copy 'to a new workbook
Set newWks = ActiveSheet
With newWks
.SaveAs Filename:="C:\" & wks.Name, FileFormat:=xlCSV
.Parent.Close savechanges:=False
End With
Next wks
MsgBox "done with: " & ActiveWorkbook.Name
End Sub
.Macro (Merge_CSV_Files) merge tất cả file CSV trong 1 thư mục (chương trình sẽ hỏi bạn thư mục nào) thành 1 file CSV và đặt vào My Document
Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, _
lpExitCode As Long) As Long
Public Const PROCESS_QUERY_INFORMATION = &H400
Public Const STILL_ACTIVE = &H103
Public Sub ShellAndWait(ByVal PathName As String, Optional WindowState)
Dim hProg As Long
Dim hProcess As Long, ExitCode As Long
'fill in the missing parameter and execute the program
If IsMissing(WindowState) Then WindowState = 1
hProg = Shell(PathName, WindowState)
'hProg is a "process ID under Win32. To get the process handle:
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, hProg)
Do
'populate Exitcode variable
GetExitCodeProcess hProcess, ExitCode
DoEvents
Loop While ExitCode = STILL_ACTIVE
End Sub
Sub Merge_CSV_Files()
Dim BatFileName As String
Dim TXTFileName As String
Dim XLSFileName As String
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim DefPath As String
Dim Wb As Workbook
Dim oApp As Object
Dim oFolder
Dim foldername
'Create two temporary file names
BatFileName = Environ("Temp") & _
"\CollectCSVData" & Format(Now, "dd-mm-yy-h-mm-ss") & ".bat"
TXTFileName = Environ("Temp") & _
"\AllCSV" & Format(Now, "dd-mm-yy-h-mm-ss") & ".txt"
'Folder where you want to save the Excel file
DefPath = Application.DefaultFilePath
If Right(DefPath, 1) <> "\" Then
DefPath = DefPath & "\"
End If
'Set the extension and file format
If Val(Application.Version) < 12 Then
'You use Excel 97-2003
FileExtStr = ".xls": FileFormatNum = -4143
Else
'You use Excel 2007
FileExtStr = ".xlsx": FileFormatNum = 51
'If you want to save as xls(97-2003 format) in 2007 use
'FileExtStr = ".xls": FileFormatNum = 56
End If
'Name of the Excel file with a date/time stamp
XLSFileName = DefPath & "MasterCSV " & _
Format(Now, "dd-mmm-yyyy h-mm-ss") & FileExtStr
'Browse to the folder with CSV files
Set oApp = CreateObject("Shell.Application")
Set oFolder = oApp.BrowseForFolder(0, "Select folder with CSV files", 512)
If Not oFolder Is Nothing Then
foldername = oFolder.Self.Path
If Right(foldername, 1) <> "\" Then
foldername = foldername & "\"
End If
'Create the bat file
Open BatFileName For Output As #1
Print #1, "Copy " & Chr(34) & foldername & "*.csv" _
& Chr(34) & " " & TXTFileName
Close #1
'Run the Bat file to collect all data from the CSV files into a TXT file
ShellAndWait BatFileName, 0
If Dir(TXTFileName) = "" Then
MsgBox "There are no csv files in this folder"
Kill BatFileName
Exit Sub
End If
'Open the TXT file in Excel
Application.ScreenUpdating = False
Workbooks.OpenText Filename:=TXTFileName, Origin:=xlWindows, StartRow _
:=1, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _
ConsecutiveDelimiter:=False, Tab:=False, Semicolon:=False, Comma:=True, _
Space:=False, Other:=False
'Save text file as a Excel file
Set Wb = ActiveWorkbook
Application.DisplayAlerts = False
Wb.SaveAs Filename:=XLSFileName, FileFormat:=FileFormatNum
Application.DisplayAlerts = True
Wb.Close savechanges:=False
MsgBox "You find the Excel file here: " & vbNewLine & XLSFileName
'Delete the bat and text file you temporary used
Kill BatFileName
Kill TXTFileName
Application.ScreenUpdating = True
End If
End Sub
Bạn chạy lần lượt 2 Macro này (Nhấn Alt+F8 để mở cửa sổ macro, sau đó chọn lần lượt từng macro và Run) thì sẽ có được 1 File CSV chứa toàn bộ dữ liệu rồi, tiếp tục bước 3
Bước 3: Có được File CSV, xóa các dòng và cột không cần thiết, chỉ giữ lại 3 cột chính là Code, Title, Singer là đủ rồi và các dòng không chứa data cũng nên xóa luôn. Tới đây thì dễ hơn là parsing của tiếng Việt vì một là mình đọc file CSV, có pattern rất rõ ràng và mỗi bài hát lại nằm 1 hàng và bài hát chỉ có 3 nội dung: Code, Title, Singer. Dưới đây là đoạn code parsing 1 bài hát tiếng anh.
/**
* Ham parsing data tu 1 bai hat
*
* @param mixed $song
*/
function parseSong($song)
{
$songData = array('code' => '', 'title' => '', 'singer' => '');
$songRawData = split(",", trim($song));
if(is_numeric($songRawData[0]) && strlen($songRawData[0]) == 5)
{
$songData['code'] = $songRawData[0];
$songData['title'] = $songRawData[1];
$songData['singer'] = strtolower($songRawData[2]);
}
return $songData;
}
—————————
Như vậy là các bạn đã biết cách mình làm sao extract được thông tin các bài hát karaoke và lưu vào cơ sở dữ liệu. Bây giờ các bạn có thể tự mình thực tập thử đi, chỉ là 1 ứng dụng nho nhỏ nhưng mình đã học được rất nhiều kiến thức sau vụ này ^^.
B.Download:
1.MySQL Dump File: File Database MySQL chứa danh sách hơn 8000 bài hát và mã bài hát mà mình đã trích xuất và lưu lại, các bạn có thể tự do dùng để import vào cơ sở dữ liệu của mình để tăng cường chức năng cho website của các bạn. Hãy nhớ, tất cả vì người dùng website!
karaoke-songlist.sql.zip
2.HTML File: Nếu bạn không phải Programmer, có thể download file ZIP này về. Trong đây có 1 file chứa danh sách bài hát tiếng Việt (từ vol 1 – 37) và danh sách bài hát tiếng Anh (hơn 4000 bài). Bạn có thể dễ dàng tra cứu vì mình đã xếp theo Alphabet.
karaoke-songlist.zip
Please Give Credit Where Credit is Due, Thank you!
P.S: Thông qua ứng dụng nho nhỏ này thì các bạn cũng biết học PHP không phải chỉ để làm web và thực tế là nó hỗ trợ rất nhiều cho mình trong việc xử lý 1 số thao tác nào đó mà cần đến lập trình (và chủ yếu là về text), vì ngoài PHP mình chẳng “biết” ngôn ngữ nào khác. Hãy sử dụng PHP như một vũ khí lợi hại nhé mọi người. Enjoying PHP!
cái này trình php cao nhắm mới hiểu dc nè… T..T
Nếu đã xài đến VBA for Excel, bạn cũng làm được code tương tự, ko cần dùng đến PHP, mất công cài server.
Dù sao bạn hướng dẫn cũng rất chi tiết và nhiệt tình. Voted!
anh co thể cho em source để học hỏi dc ko?
Từ từ rồi sẽ tới lúc đó thôi, anh đã đưa lên 2 function có nồng độ cao nhất trong cái source rồi đó :D, cố lên!
rat cam on ban ve nhung thong tin website ma ban da cho minh … minh been looking for vol 36 song list tren website biet bao lau ma k dc …. thank you rat la nhieu
Rất vui khi bài viết giúp được bạn.
anh oi! e muon lam nguyen cai web karaoke , nhung e ko biet bat dau tu dau, anh giup e duoc ko?
kimxoa@vnec.us
maivianh140285@yahoo.com
Cam on
Hihi, quan trọng là em đã biết được cái gì về web chưa, anh thì sure là không có thời gian để chỉ từ A tới Z rồi :D. Chúc em may mắn!
Không hiểu thuật toán mấy, PHP chả biết tí gì, tính làm bằng ngôn ngữ JAVA mà ko hiểu thuật toán. Bạn có thể nói rõ thêm được ko ^^
Kỹ thuật chính chỉ đơn giản là phân tích và trích xuất dữ liệu mà thôi, không có thuật toán gì phức tạp cả. Chủ yếu là nhận dạng ra pattern rồi tách.
Thank you em nhieu nhe, hom ray chi loay hoay tim list nhac de khi hat bam so cho de ma mai den hom nay moi tim duoc website nay. Het xay!
anh ơi bữa nào rảnh, anh làm 1 loạt bài về các design pattern, đặc biệt là MVC pattern được ko anh
bạn mến!
Tôi có một số diã nhạc Karaoke của Paris By Night, U Sing Along và Asia nhưng không biết làm sao để làm thành cơ sở dữ liệu theo dạng Excel hoặc Access ?
cám ơn bạn trước !
Lê Qung Tín
@Lê Quang Tín,
Chào bạn, bạn có thể dùng phần mềm “total commander” để xuất ra danh sách các tên file có trong thư mục sang file text Hoặc dùng lệnh DOS để xuất ra cây thư mục. Sau đó import vào CSDL giống bài viết.
Hix minh ko fai dan IT nen ko bt gi het,neu ban cho minh code luon de nho thang ban lam giup di chu no luoi wa’ ko chiu suy ngi, may Vol sau con biet duong ma update,minh co the dung Excel de tao dc list nhung chi la list tieng viet ko co dau thoi
Loan không biết nhiều về viết code và lập trình nhưng cũng lướt qua chiêm ngưỡng công trình của bạn như người ta ngắm vẻ đẹp của viên kim cương vậy. Thật đáng khen 1 tấm lòng biết nghĩ tới cộng đồng. Chúc bạn luôn hạnh phúc và thành công
Anh ơi Em muốn trích xuất bài hát có nhạc từ đĩa 5 số ra máy tính để hát tại nhà không cần đi ra ngoài mấy điểm karaoke.A chỉ cách giúp e với.trên trang Zinf star nhạc hay quá mà không tải về được.A có thể chỉ E tải nhạc Karaoke không lời được không Anh
Doc caj nay that su chag hju j nhug e rat kham fuc ah. E con chag bjet lam s de hat duoc bang tieg ah nua co.dj hat cu theo dah sach of ngta co j hat nay.kho de so
thank anh co the viet them cai seach nua duoc ko anh
Thank you! +1.
Cam on ban rat nhieu
Quá hay, tôi đang đi học hát karaoke đây, có lẽ cái này hữu ích lắm đây nha
bạn ơi theo mình thấy các bài hát tiếng Anh toàn bắt đầu bằng số 3, còn trong list của bạn thì toàn bắt đầu bằng số 4, khi bấm thử thì toàn ra nhạc Hoa. Bạn có biết tại sao không?
Hổi trước mình cũng lấy kiểu này, mà mình dịch ra file WORD rồi dùng C# + thư viện COM của .NET để đọc file word rồi lưu vào CSDL SQLite luôn
Thông tin bài viết rất là chi tiết hướng dẫn rất tận tình