Hi ich versuche auf Linux gerade ein Script zu basteln welche mir Links aus einer Textdatei ausliest und für diese Links dann mit BeautifulSoup als markdown inkl. Bilder speichert. Die Seite die ich dazu verwenden möchte blockiert das normale BeautifulSoup somit greife ich auf Selenium zurück der einen normalen Browser Zugriff simuliert. Mir ist Geschwindigkeit nicht wichtig - ich will ja auch den Zielserver schonen, da das nur für meine privaten Zwecke ist.
Das ist mein momentaner Code:
Starte ich mein Skript bekomme ich aktuell einen Stacktrace zurück. Und um ehrlich zu sein kenne ich mich garnicht mehr aus, bin leider ein kompletter Python Noob und weiß nichtmal wie ich das debugge...
Kann mir jemand einen Hinweis geben wo ich einen groben Schnitzer habe? Es soll schon eine Lernerfahrung für mich sein das Projekt aber ich dachte nicht, dass es so zeitintensiv wird...
Das ist mein momentaner Code:
Python:
import os
import time
import requests
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
# Function to create a valid folder name from the blog title
def create_folder_name(blog_title):
return ''.join(c if c.isalnum() else '_' for c in blog_title)
# Function to download an image and save it locally
def download_image(img_url, folder_path):
response = requests.get(img_url)
if response.status_code == 200:
img_name = os.path.basename(urlparse(img_url).path)
img_dir = os.path.join(folder_path, 'img')
os.makedirs(img_dir, exist_ok=True)
img_path = os.path.join(img_dir, img_name)
with open(img_path, 'wb') as f:
f.write(response.content)
return img_path
return None
# Function to fetch and parse a blog post
def fetch_blog_post(post_url, base_dir, chrome_binary, chrome_driver_path):
options = Options()
options.binary_location = chrome_binary
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
service = Service(chrome_driver_path)
driver = webdriver.Chrome(service=service, options=options)
driver.get(post_url)
try:
# Wait until the article content is present on the page
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, 'article'))
)
# Get the page source after waiting for the page to load
page_source = driver.page_source
# Use BeautifulSoup to parse the page source
soup = BeautifulSoup(page_source, 'html.parser')
# Extract the blog title
title_element = soup.find('title')
if title_element:
blog_title = title_element.text.strip().split('|')[0].strip()
else:
raise Exception("Title element not found")
except Exception as e:
print(f"Error fetching blog title from {post_url}: {e}")
driver.quit()
return
folder_name = create_folder_name(blog_title)
post_dir = os.path.join(base_dir, folder_name)
os.makedirs(post_dir, exist_ok=True)
md_content = f"# {blog_title}\n\n"
try:
article = soup.find('article')
if article:
for element in article.find_all(['p', 'figure']):
if element.name == 'p':
md_content += element.get_text() + "\n\n"
elif element.name == 'figure':
img_tag = element.find('img')
if img_tag and img_tag.get('srcset'):
# Select the best quality image from srcset
srcset = img_tag['srcset'].split(',')
best_img_url = srcset[-1].split()[0] # Choose the last one assuming it's the best quality
best_img_url = urljoin(post_url, best_img_url)
img_path = download_image(best_img_url, post_dir)
if img_path:
md_content += f"![{os.path.basename(img_path)}](img/{os.path.basename(img_path)})\n\n"
else:
print(f"No article found at {post_url}")
except Exception as e:
print(f"Error parsing content from {post_url}: {e}")
with open(os.path.join(post_dir, 'post.md'), 'w') as f:
f.write(md_content)
print(f"Saved post: {blog_title}")
driver.quit()
# Main function to fetch multiple blog posts from a file
def main():
base_dir = "permanentstyle"
os.makedirs(base_dir, exist_ok=True)
with open('input.txt', 'r') as file:
post_urls = [line.strip() for line in file if line.strip()]
chrome_binary = '/usr/bin/chromium' # Path to Chromium executable
chrome_driver_path = '/home/p/chromedriver' # Download from https://sites.google.com/chromium.org/driver/
for post_url in post_urls:
fetch_blog_post(post_url, base_dir, chrome_binary, chrome_driver_path)
if __name__ == "__main__":
main()
Starte ich mein Skript bekomme ich aktuell einen Stacktrace zurück. Und um ehrlich zu sein kenne ich mich garnicht mehr aus, bin leider ein kompletter Python Noob und weiß nichtmal wie ich das debugge...
Kann mir jemand einen Hinweis geben wo ich einen groben Schnitzer habe? Es soll schon eine Lernerfahrung für mich sein das Projekt aber ich dachte nicht, dass es so zeitintensiv wird...