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
İşte (Ubuntu üzerinde python3.5 üzerinde test script python3 versiyonudur 17.10 ).
Nasıl kullanılır:
- Kullanmak için her iki kodu da dosyalara koyun. Örneğin, kod dosyası
script.py
ve paket dosyası requirement.txt
.
- Koş
pip install -r requirement.txt
.
- Komut dosyasını örnek olarak çalıştırın
python3 script.py pa4080
Birkaç kütüphane kullanır:
Programı daha da geliştirmek için bilinmesi gerekenler (gerekli paketin dokümanı hariç):
- python kütüphanesi: asyncio, json ve urllib.parse
- css seçicileri ( mdn web belgeleri ), ayrıca bazı html. ayrıca bu makale gibi tarayıcınızda css seçiciyi nasıl kullanacağınıza bakın
Nasıl çalışır:
- Önce basit bir html indirici oluşturuyorum. Aiohttp doc'de verilen örnekten değiştirilmiş versiyon.
- Bundan sonra kullanıcı adı ve çıktı dosya adını kabul eden basit komut satırı ayrıştırıcısı oluşturulur.
- İş parçacığı bağlantıları ve ana makale için bir ayrıştırıcı oluşturun. PDB ve basit URL manipülasyonu kullanarak iş yapmak gerekir.
- Fonksiyonu birleştirin ve ana makaleyi json üzerine koyun, böylece diğer program daha sonra işleyebilir.
Bazı fikirler, böylece daha da geliştirilebilir
- Tarih modülü bağlantısını kabul eden başka bir alt komut oluşturun: tarih modülünü kendi işlevine ayrıştırma yöntemini ayırarak ve yeni alt komutla birleştirerek yapılabilir.
- Tarih modülü bağlantısını önbelleğe alma: iş parçacığı bağlantısını aldıktan sonra önbellek json dosyası oluşturun. böylece program bağlantıyı tekrar ayrıştırmak zorunda kalmaz. veya eşleşmese bile tüm ana başlık makalesini önbelleğe al
Bu en şık cevap değil, ama bence bash cevabı kullanmaktan daha iyi.
- Çapraz platformda kullanılabileceği anlamına gelen Python kullanır.
- Basit kurulum, gerekli tüm paketler pip kullanılarak kurulabilir
- Daha da geliştirilebilir, program daha okunabilir, daha kolay geliştirilebilir.
- Bash betiği ile aynı işi sadece 13 dakika boyunca yapar .
sudo apt install python3-bs4 python3-click python3-aiohttp python3-async
ancak bulamıyorum - hangi pakettenasync_timeout
geliyor?