๐Pyppeteer ๋ฐ๋ชจ
Pypeter๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
Python
์ฌ์ฉSelenium
์ ๊ธฐ์ฌ๊ฐ ๋๋์ผ๋ก ํ๋ ธ๊ณ , ๊ทธ ์ค์์๋ ์ฌ์ฉPyppeteer
๋ Qita ๋ณด๋Pyppetter
์ ๊ดํ Qita ๋ฌธ์ฅ ๋ช ๊ถ์ ์ฝ๊ณ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ Pyppetter
์ด์Puppeteer๏ผJavascript๏ผ
์ด์๊ธฐ ๋๋ฌธ์ Puppeteer
์ ๋ฌธ์ฅ ๋ช ํธ์ ํ์ธํ๋ค์ฐธ๊ณ ์๋ฃ
์ค์นํ๋ค.
pip3 install
$ pip3 install pyppeteer
๊ฐ์ ธ์ค๊ธฐ
๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ
import asyncio
from pyppeteer import launch
์ฌ์ ์ค๋น
์์ ์ ๋ ฅ ํ์ธ
ใใญในใใใใฏใน
ใใญในใใใใฏใน
ใใญในใใใใฏใน
ใใญใใใใฆใณใชในใ
ใใงใใฏใใใฏใน
์๋ ์ ๋ ฅ ํ์ธ ์ปจ๋ํฐ
์๋ ์ ๋ ฅ ์์ ์ ๋ฆฌํ๊ธฐ
์์ ์ ๋ ฅ ์ค๋น
faker
ํจํค์ง๋ฅผ ์ฌ์ฉํ์ฌ ๊ทธ ์คํ์ผ์ ๋ฉ์ผ ์ฃผ์๋ฅผ ์๋์ผ๋ก ์์ฑ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๋ ๋ฐฉ๋ฒ์ [๋ถ๊ฐ]๋ก ์ค๋ช ํ๋ค
ํจ์ ๋ง๋๋ ๋ฒ
pyppeteer
์์ ์ํ๋๋ ๋ชจ๋ ์น ์์
์ ๋น๋๊ธฐ์async def ้ขๆฐๅ(...)
await ้ขๆฐๅ(...)
์ถ๊ฐํ๋ ๊ฒ์ ์์ด๋ฒ๋ฆฌ๊ฑฐ๋
async
๋๋ await
์คํํ๋ฉด ์์ ๋จน๊ธฐ ๋๋ฌธ์ ์์ ํ ์ ์์ต๋๋ค๋ธ๋ผ์ฐ์ ์์
headless Chrome
์๋์ด ๊ฑธ๋ฆฐ ๊ฒ ๊ฐ์๋ฐbrowser = await launch()
headless=False
browser = await launch(headless=False)
ํ์ด์ง ์ก์ธ์ค
page = await browser.newPage()
await page.goto(url)
์ ๋ ฅ ํ ์คํธ ์์
ใปใฌใฏใฟ
๋ฐ ๅ
ฅๅใใๅค
๋ฅผ ์ง์ ํ๋ฉด OKawait page.type('ใปใฌใฏใฟ', 'ๅ
ฅๅใใๅค')
<input type="text" name="name_last" id="name_last" value="">
<input type="text" name="name_first" id="name_first" value="">
<input type="text" name="kana_last" id="kana_last" value="">
<input type="text" name="kana_first" id="kana_first" value="">
<input type="text" name="mail" id="mail" value="">
<input type="text" name="mail_re" id="mail_re" value="">
id
์์ฑ์ ์ฌ์ฉํ์ฌ ์ง์ ํ๋ ๊ฒ์ ๋งค์ฐ ๊ฐ๋จํ ๊ฒ ๊ฐ๋คinput[name="name"]
๋ OK(์๋ง)await page.type('#name_last', '็ซ้')
await page.type('#name_first', '็ญๆฒป้')
await page.type('#kana_last', 'ใใพใฉ')
await page.type('#kana_first', 'ใใใใใ')
await page.type('#mail', '[email protected]')
await page.type('#mail_re', '[email protected]')
๋๋กญ๋ค์ด ๋ฉ๋ด์์ ์ ํ
ใปใฌใฏใฟ
๋ฐ ้ธๆใใๅค
๋ฅผ ์ง์ ํ๋ฉด OKawait page.select('ใปใฌใฏใฟ', '้ธๆใใๅค')
ใปใฌใฏใฟ
้ธๆใใๅค
ํ์ธvalue
์ ์ค์ ๋ ๊ฐ<select id="age" name="age">
<option value="" selected="selected">้ธๆใใฆใใ ใใ</option>
<option value="1">10ไปฃ</option>
<option value="2">20ไปฃ</option>
<option value="3">30ไปฃ</option>
</select>
id
์ ์ฌ์ฉํ์ฌ ์ง์ await page.select('#age', '1')
import random
await page.select('#age', str(random.randint(1, 3)))
ํ์ธ๋์ ์ ํํฉ๋๋ค.
await page.click('ใปใฌใฏใฟ')
ใปใฌใฏใฟ
<input type="checkbox" name="web" id="web" value="1">
<label for="web">ใฆใงใใตใคใ</label>
<br>
<input type="checkbox" name="tw" id="tw" value="2">
<label for="tw">Twitter</label>
<br>
<input type="checkbox" name="fb" id="fb" value="3">
<label for="fb">Facebook</label>
<br>
<input type="checkbox" name="mz" id="mz" value="4">
<label for="magazine">ใกใผใซใใฌใธใณ</label>
id
์ ์ฌ์ฉํ์ฌ ์ง์ await page.click('#web')
await page.click('#fb')
์ ๋ ฅ ์ฐฝ ๋ณด๋ด๊ธฐ
page.click
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค์ ๋ ฅ ์ฐฝ (๋ณด๋ด๊ธฐ ์ฐฝ)
<input type="submit" name="__send" id="__send" value="ๆฌกใธ โ">
name
์์ฑ ์ง์ ์ฌ์ฉpage.waitForNavigation()
await asyncio.wait([
page.click('input[name="__send"]'),
page.waitForNavigation(),
])
์บก์ฒ ์ ์ฅ
page.setViewport
๋ก ํ๋ฉด ํฌ๊ธฐ ์ค์ await page.setViewport({'width': 800, 'height': 1000})
await page.screenshot(path='ss/screenshot.png', fullPage=True)
์ ๋ ฅ ํ ์คํธ ์ํ
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
if __name__ == "__main__":
N = 5 ## <== ใใใฎๅคใ็ดๆฅๆธใๆใใฆใๆงๅญใใฟใชใใใในใ
for i in range(N):
print('=' * 30)
print(f'TEST [{i+1:3d}/{N:3d}]')
asyncio.get_event_loop().run_until_complete(main())
time.sleep(random.randint(1, 30)) ## <== ๆปๆใใฆใใใใใใชใใใจใใๆฐๆใกใฎ่กจใ
์คํจํ ์ด์ผ๊ธฐ๋ก์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฐ๋ฉด์ ๋๋ฒ๊น
์ ํ ๋ ๋ฐฉ๋ฌธ ํ์ด์ง๊ฐ ์ฐจ๋จ๋์๋ค.ํ ๋๋ ๊ด๊ณ์์๊ฒ ๋ฏธ๋ฆฌ ํ์ธํ๊ณ ์๋ ค์ฃผ๋ ๊ฒ์ด ์ข๋ค.๊ฒฝํ: ํ ์คํธ์ฉ ๋ฐ์ดํฐ ์์ฑ
faker
,pykakasi
,random
ํฌ์ฅ์ ์ฌ์ฉํ์ฌ ๊ฐ์ง๋ก ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์๋ค$ pip3 install faker
$ pip3 install pykakasi
์ซ์ ์์ฑ
input
์ value
๋ฒ์ ๋ด์์ ๋ฌด์์ ์์ฑ ์ ์import random
random.randint(1, 5)
์์ฑ ์ด๋ฆ
faker.Faker
์ผ๋ณธ์ด ๋ชจ๋ja_JP
๋ก ๊ฐ์ฒด ๋ง๋ค๊ธฐlast_name
์ ์ด๋ฆfirst_name
from faker import Faker
fakejp = Faker('ja_JP')
name_last = fakejp.last_name()
name_first = fakejp.first_name()
await page.type('#name_last', name_last)
await page.type('#name_first', name_first)
์ฃผ์๊ฐ๋ช ์ ๋ง๋ค๋ค
๋ฌธ์ ์
faker
์์ ์์ฑ๋ ๋ก์ผํฌ๋ ๊ฐ๋ช
์ด๋คํด๊ฒฐ์ฑ
pykakasi
์์์ ์์ฑ๋ ์ด๋ฆ์ ํ๊ฐ๋ช
์ผ๋ก ๋ณํimport pykakasi
kks = pykakasi.kakasi()
kana_last = kks.convert(name_last)[0]['hira']
kana_first = kks.convert(name_first)[0]['hira']
await page.type('#kana_last', kana_last)
await page.type('#kana_first', kana_first)
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐Pyppeteer ๋ฐ๋ชจ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://zenn.dev/shotakaha/articles/5885cac71af6dc966e97ํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค