Scrape Data dari Gambar dengan Python |
Kekerasan terhadap perempuan kerapkali terjadi di Indonesia. Berdasarkan data yang berasal dari Portal Simfoni Kementerian PPPA, jumlah kasus kekerasan terhadap perempuan di tahun 2018 saja mencapai 12.867 kasus.
Fakta miris juga diungkap oleh Kemnas Perempuan, dalam sehari saja, terdapat setidaknya 35 perempuan, termasuk anak perempuan yang mengalami tindak kekerasan. Ini mengartikan, bahwa dalam sejam, terdapat 3 kasus kekerasan terhadap perempuan di Indonesia selama 2018.
Iseng-iseng, saya membaca ulasan media Tempo dengan data dari Kementerian PPPA tersebut. Dengan narasi yang bernas, ulasan mengenai kekerasan terhadap perempuan di Indonesia selama 2018 dibingkai dengan baik melalui sebuah infografis (dalam bentuk gambar). Saya kemudian terpikir bila suatu data yang esensinya penting untuk dibagipakaikan lantas bentuknya dalam image atau gambar, lantas bagaimana cara mendapatkannya?
Tebersitlah saya untuk belajar bagaimana melakukan scraping data yang terkandung pada suatu gambar. Untuk melakukan scrape data pada gambar, pertama kita perlu melakukan instalasi sebuah aplikasi yang dapat "membaca" teks di dalam gambar (bisa diunduh pada tautan berikut). Sedangkan infografisnya adalah sebagai berikut:
Infografis kekerasan terhadap perempuan selama 2018, sumber: grafis.tempo.co (2018) |
Setelah diinstal di direktori C, langkah-langkah melakukan scrape data pada infografis Tempo adalah sebagai berikut:
from PIL import Image
from pytesseract import pytesseract
# Defining paths to tesseract.exe
# and the image we would be using
path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
image_path = r"C:\Users\Joko Ade\Downloads\kkp.png"
# Opening the image & storing it in an image object
img = Image.open(image_path)
img
#Memotong bagian yang penting
image_path = r"C:\Users\Joko Ade\Downloads\kkpcopy.png"
img = Image.open(image_path)
img
#Mengekstrak path pada image atau gambar
pytesseract.tesseract_cmd = path_to_tesseract
#Memilah antara obyek gambar (path)
#dengan teks string menggunakan fungsi image_to_string()
#Mengekstraks teks dari gambar
text = pytesseract.image_to_string(img)
text
'Pacar 1.528\nAyah kandung 425\nPaman 322\n\nAyah tii 205\nSuami 192\n\nKakak kandung 89\nKakak ipar 51\n\nSepupu fle\nMajikan 2h\nMantan suami 12\nKakaktiri 10\nMantan pacar\n\n8\nKakektiri 3\nAyah angkat = 2\nAyahasuh 2\nIbu 2\n\nKakak angkat = 1\nPRT laki-laki 1\n'
#Konversi dalam bentuk list dengan membersihkan karakter \n
import re
text2 = re.findall('(.+)', text)
text2
['Pacar 1.528', 'Ayah kandung 425', 'Paman 322', 'Ayah tii 205', 'Suami 192', 'Kakak kandung 89', 'Kakak ipar 51', 'Sepupu fle', 'Majikan 2h', 'Mantan suami 12', 'Kakaktiri 10', 'Mantan pacar', '8', 'Kakektiri 3', 'Ayah angkat = 2', 'Ayahasuh 2', 'Ibu 2', 'Kakak angkat = 1', 'PRT laki-laki 1']
#Mengubah menjadi dataframe
df = pd.DataFrame({'teks':text2})
df
teks | |
---|---|
0 | Pacar 1.528 |
1 | Ayah kandung 425 |
2 | Paman 322 |
3 | Ayah tii 205 |
4 | Suami 192 |
5 | Kakak kandung 89 |
6 | Kakak ipar 51 |
7 | Sepupu fle |
8 | Majikan 2h |
9 | Mantan suami 12 |
10 | Kakaktiri 10 |
11 | Mantan pacar |
12 | 8 |
13 | Kakektiri 3 |
14 | Ayah angkat = 2 |
15 | Ayahasuh 2 |
16 | Ibu 2 |
17 | Kakak angkat = 1 |
18 | PRT laki-laki 1 |
#Menghapus baris ke-12 dalam dataframe
df2 = df.drop(labels = 12)
df2
teks | |
---|---|
0 | Pacar 1.528 |
1 | Ayah kandung 425 |
2 | Paman 322 |
3 | Ayah tii 205 |
4 | Suami 192 |
5 | Kakak kandung 89 |
6 | Kakak ipar 51 |
7 | Sepupu fle |
8 | Majikan 2h |
9 | Mantan suami 12 |
10 | Kakaktiri 10 |
11 | Mantan pacar |
13 | Kakektiri 3 |
14 | Ayah angkat = 2 |
15 | Ayahasuh 2 |
16 | Ibu 2 |
17 | Kakak angkat = 1 |
18 | PRT laki-laki 1 |
#Memperbaiki sejumlah teks, ejaan, dan data sesuai gambar
#karena beberapa angka dan teks tidak terekstraks sempurna
df3 = df2.replace('Mantan pacar',
'Mantan pacar 8', regex=True)
df3 = df3.replace('=', '', regex=True)
df3 = df3.replace('fle', '44', regex=True)
df3 = df3.replace('2h', '24', regex=True)
df3 = df3.replace('Ayah tii', 'Ayah tiri', regex=True)
df3
teks | |
---|---|
0 | Pacar 1.528 |
1 | Ayah kandung 425 |
2 | Paman 322 |
3 | Ayah tiri 205 |
4 | Suami 192 |
5 | Kakak kandung 89 |
6 | Kakak ipar 51 |
7 | Sepupu 44 |
8 | Majikan 24 |
9 | Mantan suami 12 |
10 | Kakaktiri 10 |
11 | Mantan pacar 8 |
13 | Kakektiri 3 |
14 | Ayah angkat 2 |
15 | Ayahasuh 2 |
16 | Ibu 2 |
17 | Kakak angkat 1 |
18 | PRT laki-laki 1 |
#Ekstraksi jumlah kasus kekerasan dengan korban Perempuan selama 2018
df3['Jumlah'] =
df3['teks'].astype('str').str.extractall('(\d+)').unstack().fillna('').sum(axis=1).astype(int)
df3
teks | Jumlah | |
---|---|---|
0 | Pacar 1.528 | 1528 |
1 | Ayah kandung 425 | 425 |
2 | Paman 322 | 322 |
3 | Ayah tiri 205 | 205 |
4 | Suami 192 | 192 |
5 | Kakak kandung 89 | 89 |
6 | Kakak ipar 51 | 51 |
7 | Sepupu 44 | 44 |
8 | Majikan 24 | 24 |
9 | Mantan suami 12 | 12 |
10 | Kakaktiri 10 | 10 |
11 | Mantan pacar 8 | 8 |
13 | Kakektiri 3 | 3 |
14 | Ayah angkat 2 | 2 |
15 | Ayahasuh 2 | 2 |
16 | Ibu 2 | 2 |
17 | Kakak angkat 1 | 1 |
18 | PRT laki-laki 1 | 1 |
#Ekstraksi pelaku kekerasan terhadap perempuan selama 2018
df3['Pelaku'] =
df3['teks'].astype('str').replace('(\d)','',regex=True).replace('[.]','',regex=True)
df3
teks | Jumlah | Pelaku | |
---|---|---|---|
0 | Pacar 1.528 | 1528 | Pacar |
1 | Ayah kandung 425 | 425 | Ayah kandung |
2 | Paman 322 | 322 | Paman |
3 | Ayah tiri 205 | 205 | Ayah tiri |
4 | Suami 192 | 192 | Suami |
5 | Kakak kandung 89 | 89 | Kakak kandung |
6 | Kakak ipar 51 | 51 | Kakak ipar |
7 | Sepupu 44 | 44 | Sepupu |
8 | Majikan 24 | 24 | Majikan |
9 | Mantan suami 12 | 12 | Mantan suami |
10 | Kakaktiri 10 | 10 | Kakaktiri |
11 | Mantan pacar 8 | 8 | Mantan pacar |
13 | Kakektiri 3 | 3 | Kakektiri |
14 | Ayah angkat 2 | 2 | Ayah angkat |
15 | Ayahasuh 2 | 2 | Ayahasuh |
16 | Ibu 2 | 2 | Ibu |
17 | Kakak angkat 1 | 1 | Kakak angkat |
18 | PRT laki-laki 1 | 1 | PRT laki-laki |
#Aktivasi beberapa package untuk visualisasi
from pywaffle import Waffle
import matplotlib.pyplot as plt
import random
#Mengenerate 18 warna random untuk visualisasi 18 pelaku kekerasan terhadap perempuan selama 2018
jumwar = 18
warna = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])
for i in range(jumwar)]
print(warna)
['#5155F2', '#7BC735', '#3022A8', '#8E9561', '#2FBCF4', '#E94282', '#DFC570', '#A4CF2B', '#D0C248', '#AAF70E', '#829484', '#233995', '#6CD03A', '#06EF64', '#BCAD8F', '#886475', '#A6DFB9', '#5D5B1E']
#Visualisasi Waffle Plot dengan custome image perempuan
fig = plt.figure(figsize = (25,15),
FigureClass=Waffle,
rows=18,
values=df3.Jumlah,
colors=warna,
legend={'loc': 'upper left', 'bbox_to_anchor': (1,1)},
icons='female', icon_size=15,
icon_legend=True
)
#Visualisasi bar plot
df3_sort = df3.sort_values(by = "Jumlah")
plt.figure(figsize=(15,15))
plt.barh(df3_sort.Pelaku, width = df3_sort.Jumlah)
plt.xlabel("Jumlah (Kasus)")
plt.ylabel("Pelaku")
plt.title("Kasus Kekerasan Terhadap Perempuan menurut Pelakunya Tahun 2018")
plt.show()
Terlihat bahwa pelaku paling banyak melakukan kekerasan terhadap perempuan selama 2018 adalah Pacar, diikuti oleh Ayah Kandung, dan Paman.
Demikian sedikit sharing kita kali ini, semoga bermanfaat. Selamat mempraktikkan!