script.py
:
#!/usr/bin/python3
from urllib.parse import urljoin
import json
import bs4
import click
import aiohttp
import asyncio
import async_timeout
BASE_URL = 'http://e-bane.net'
async def fetch(session, url):
try:
with async_timeout.timeout(20):
async with session.get(url) as response:
return await response.text()
except asyncio.TimeoutError as e:
print('[{}]{}'.format('timeout error', url))
with async_timeout.timeout(20):
async with session.get(url) as response:
return await response.text()
async def get_result(user):
target_url = 'http://e-bane.net/modules.php?name=Stories_Archive'
res = []
async with aiohttp.ClientSession() as session:
html = await fetch(session, target_url)
html_soup = bs4.BeautifulSoup(html, 'html.parser')
date_module_links = parse_date_module_links(html_soup)
for dm_link in date_module_links:
html = await fetch(session, dm_link)
html_soup = bs4.BeautifulSoup(html, 'html.parser')
thread_links = parse_thread_links(html_soup)
print('[{}]{}'.format(len(thread_links), dm_link))
for t_link in thread_links:
thread_html = await fetch(session, t_link)
t_html_soup = bs4.BeautifulSoup(thread_html, 'html.parser')
if is_article_match(t_html_soup, user):
print('[v]{}'.format(t_link))
# to get main article, uncomment below code
# res.append(get_main_article(t_html_soup))
# code below is used to get thread link
res.append(t_link)
else:
print('[x]{}'.format(t_link))
return res
def parse_date_module_links(page):
a_tags = page.select('ul li a')
hrefs = a_tags = [x.get('href') for x in a_tags]
return [urljoin(BASE_URL, x) for x in hrefs]
def parse_thread_links(page):
a_tags = page.select('table table tr td > a')
hrefs = a_tags = [x.get('href') for x in a_tags]
# filter href with 'file=article'
valid_hrefs = [x for x in hrefs if 'file=article' in x]
return [urljoin(BASE_URL, x) for x in valid_hrefs]
def is_article_match(page, user):
main_article = get_main_article(page)
return main_article.text.startswith(user)
def get_main_article(page):
td_tags = page.select('table table td.row1')
td_tag = td_tags[4]
return td_tag
@click.command()
@click.argument('user')
@click.option('--output-filename', default='out.json', help='Output filename.')
def main(user, output_filename):
loop = asyncio.get_event_loop()
res = loop.run_until_complete(get_result(user))
# if you want to return main article, convert html soup into text
# text_res = [x.text for x in res]
# else just put res on text_res
text_res = res
with open(output_filename, 'w') as f:
json.dump(text_res, f)
if __name__ == '__main__':
main()
requirement.txt
:
aiohttp>=2.3.7
beautifulsoup4>=4.6.0
click>=6.7
นี่คือสคริปต์เวอร์ชั่น python3 (ทดสอบบน python3.5 บน Ubuntu 17.10 )
วิธีใช้:
- หากต้องการใช้งานให้วางโค้ดทั้งสองไว้ในไฟล์ ตัวอย่างเช่นไฟล์รหัสและแฟ้มแพคเกจ
script.py
requirement.txt
pip install -r requirement.txt
วิ่ง
- รันสคริปต์เป็นตัวอย่าง
python3 script.py pa4080
มันใช้ห้องสมุดหลายแห่ง:
สิ่งที่ควรทราบเพื่อพัฒนาโปรแกรมเพิ่มเติม (นอกเหนือจากเอกสารของแพ็คเกจที่ต้องการ):
- หลามไลบรารี: asyncio, json และ urllib.parse
- ตัวเลือก css ( mdn web docs ) รวมทั้ง html ด้วย ดูวิธีการใช้ css selector บนเบราว์เซอร์ของคุณเช่นบทความนี้
มันทำงานอย่างไร:
- ก่อนอื่นฉันสร้างเครื่องมือดาวน์โหลด HTML แบบง่าย มันเป็นรุ่นที่ปรับเปลี่ยนจากตัวอย่างที่กำหนดใน aiohttp doc
- หลังจากนั้นสร้างตัวแยกวิเคราะห์บรรทัดคำสั่งอย่างง่ายซึ่งยอมรับชื่อผู้ใช้และชื่อไฟล์เอาต์พุต
- สร้าง parser สำหรับลิงค์เธรดและบทความหลัก การใช้ pdb และการจัดการ URL อย่างง่ายควรทำงาน
- รวมฟังก์ชั่นและวางบทความหลักใน json เพื่อให้โปรแกรมอื่นสามารถประมวลผลได้ในภายหลัง
ความคิดบางอย่างเพื่อให้สามารถพัฒนาต่อไป
- สร้างคำสั่งย่อยอื่นที่ยอมรับการเชื่อมโยงโมดูลวันที่: สามารถทำได้โดยการแยกวิธีการแยกวิเคราะห์โมดูลวันที่เพื่อฟังก์ชั่นของตัวเองและรวมกับคำสั่งย่อยใหม่
- การแคชลิงก์โมดูลวันที่: สร้างไฟล์ json แคชหลังจากรับลิงก์เธรด ดังนั้นโปรแกรมไม่จำเป็นต้องแยกวิเคราะห์ลิงก์อีกครั้ง หรือแม้กระทั่งเพียงแค่แคชบทความหลักทั้งกระทู้แม้ว่าจะไม่ตรงกัน
นี่ไม่ใช่คำตอบที่หรูหราที่สุด แต่ฉันคิดว่ามันดีกว่าการใช้คำตอบ bash
- มันใช้ Python ซึ่งหมายความว่ามันสามารถใช้ข้ามแพลตฟอร์มได้
- ติดตั้งง่ายแพคเกจที่จำเป็นทั้งหมดสามารถติดตั้งได้โดยใช้ pip
- สามารถพัฒนาเพิ่มเติมอ่านโปรแกรมได้ง่ายขึ้นสามารถพัฒนาได้ง่ายขึ้น
- มันไม่งานเดียวกันเป็นสคริปต์ทุบตีเท่านั้นสำหรับ13 นาที
sudo apt install python3-bs4 python3-click python3-aiohttp python3-async
แต่ฉันหาไม่ได้ - แพคเกจใดasync_timeout
มาจากไหน