5.5 Crawl4AI 项目实践案例分析 Crawl4AI 项目实践案例分析:深入解析与代码实践 5.5.1 案例一:学术论文信息爬取与分析 场景描述: 我们需要爬取某个特定领域(例如:人工智能)的学术论文信息,包括论文标题、作者、摘要、发表期刊/会议、发表年份、引用次数等。目标是从多个学术网站(例如:Google Scholar, arXiv, IEEE Xplore)收集数据,并进行数据清洗、存储和分析,最终实现对该领域研究趋势的初步了解。 1. 爬虫设计: 针对多源数据,我们需要设计一个模块化的爬虫架构,针对每个网站编写独立的爬虫模块。 2. 代码实践: 这里以 Google Scholar 为例,展示爬虫的核心代码。 使用 Python 的 库进行网页请求, 库进行页面解析。
场景描述: 我们需要爬取某个特定领域(例如:人工智能)的学术论文信息,包括论文标题、作者、摘要、发表期刊/会议、发表年份、引用次数等。目标是从多个学术网站(例如:Google Scholar, arXiv, IEEE Xplore)收集数据,并进行数据清洗、存储和分析,最终实现对该领域研究趋势的初步了解。
1. 爬虫设计:
针对多源数据,我们需要设计一个模块化的爬虫架构,针对每个网站编写独立的爬虫模块。
2. 代码实践:
这里以 Google Scholar 为例,展示爬虫的核心代码。 使用 Python 的 requests 库进行网页请求,BeautifulSoup4 库进行页面解析。
import requests from bs4 import BeautifulSoup import re import pandas as pd def google_scholar_crawler(keyword, num_pages=1): """ 爬取 Google Scholar 上特定关键词的论文信息。 Args: keyword (str): 搜索关键词。 num_pages (int): 爬取的页数。 Returns: list: 包含论文信息的列表。 """ results = [] for page in range(num_pages): start = page * 10 # Google Scholar 每页显示 10 篇论文 url = f"https://scholar.google.com/scholar?q={keyword}&hl=en&start={start}" try: response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=10) response.raise_for_status() # 检查请求是否成功 soup = BeautifulSoup(response.content, 'html.parser') papers = soup.find_all('div', class_='gs_ri') for paper in papers: title = paper.find('h3', class_='gs_rt').text if paper.find('h3', class_='gs_rt') else 'N/A' authors = paper.find('div', class_='gs_a').text if paper.find('div', class_='gs_a') else 'N/A' abstract_element = paper.find('div', class_='gs_rs') abstract = abstract_element.text if abstract_element else 'N/A' citation_link = paper.find('div', class_='gs_fl').find_all('a')[-1]['href'] if paper.find('div', class_='gs_fl') and len(paper.find('div', class_='gs_fl').find_all('a')) > 0 else None citation_count = 0 if citation_link: try: citation_page = requests.get("https://scholar.google.com" + citation_link, headers={'User-Agent': 'Mozilla/5.0'}, timeout=10) citation_page.raise_for_status() citation_soup = BeautifulSoup(citation_page.content, 'html.parser') citation_count_str = citation_soup.find('div', id="gs_ab_md").text citation_count = int(re.search(r'\d+', citation_count_str).group()) if re.search(r'\d+', citation_count_str) else 0 except requests.exceptions.RequestException as e: print(f"Error fetching citation data: {e}") publication_info = paper.find('div', class_='gs_a').text if paper.find('div', class_='gs_a') else 'N/A' year = re.search(r'\d{4}', publication_info) year = int(year.group(0)) if year else None results.append({ 'title': title, 'authors': authors, 'abstract': abstract, 'citation_count': citation_count, 'year': year }) except requests.exceptions.RequestException as e: print(f"Error fetching page {page+1}: {e}") break # 停止爬取,避免被封禁 return results # 示例:爬取 "Artificial Intelligence" 关键词的前 3 页结果 if __name__ == '__main__': data = google_scholar_crawler("Artificial Intelligence", num_pages=3) df = pd.DataFrame(data) print(df.head()) df.to_csv("ai_papers.csv", index=False) # 保存到 CSV 文件
代码详解:
google_scholar_crawler(keyword, num_pages) 函数: 接受关键词和页数作为参数,返回包含论文信息的列表。
requests.get(url): 使用 requests 库发送 HTTP 请求,获取网页内容。 设置 User-Agent 避免被识别为爬虫。
BeautifulSoup(response.content, 'html.parser'): 使用 BeautifulSoup 解析 HTML 内容。
soup.find_all('div', class_='gs_ri'): 找到所有包含论文信息的 div 元素。
信息提取: 使用 find 方法提取论文标题、作者、摘要等信息。
错误处理: 使用 try...except 块处理网络请求错误,避免程序崩溃。
df = pd.DataFrame(data): 将爬取到的数据转换为 Pandas DataFrame,方便后续处理和分析。
df.to_csv("ai_papers.csv", index=False): 将数据保存到 CSV 文件。
3. 数据清洗与存储:
数据清洗: 去除重复数据,处理缺失值,统一数据格式。例如,将作者信息分割成独立的作者列表,将年份转换为统一的格式。
数据存储: 可以选择将数据存储到 CSV 文件、JSON 文件或数据库中(例如:MySQL, MongoDB)。
4. 数据分析:
趋势分析: 统计每年发表的论文数量,分析研究热点随时间的变化趋势。
关键词分析: 提取论文摘要中的关键词,分析该领域的研究重点。
作者分析: 分析高产作者及其研究方向。
引用分析: 分析高引用论文及其研究价值。
5. 优化方向:
使用代理 IP: 避免 IP 被封禁。
设置请求间隔: 减缓爬取速度,避免对服务器造成过大压力。
使用多线程/异步爬虫: 提高爬取效率。
使用更强大的解析库: 例如:lxml,提高解析速度。
使用缓存: 减少重复请求。
场景描述: 我们需要监控特定电商平台(例如:Amazon, JD.com)上特定商品的价格,当价格低于某个阈值时,发送邮件/短信通知。
1. 爬虫设计:
2. 代码实践:
这里以 Amazon 为例,展示爬虫的核心代码。
import requests from bs4 import BeautifulSoup import smtplib from email.mime.text import MIMEText import time def amazon_price_tracker(url, threshold_price): """ 监控 Amazon 商品价格,低于阈值发送邮件通知。 Args: url (str): Amazon 商品链接。 threshold_price (float): 价格阈值。 """ try: response = requests.get(url, headers={'User-Agent': 'Mozilla/5.0'}, timeout=10) response.raise_for_status() soup = BeautifulSoup(response.content, 'html.parser') # 找到价格元素,可能需要根据实际页面结构调整选择器 price_element = soup.find('span', class_='a-offscreen') # 假设价格在 class 为 a-offscreen 的 span 标签中 if not price_element: print("Price element not found.") return price_str = price_element.text.strip().replace('$', '').replace(',', '') price = float(price_str) print(f"Current price: ${price}") if price < threshold_price: send_notification_email(url, price, threshold_price) print("Notification email sent.") except requests.exceptions.RequestException as e: print(f"Error fetching price: {e}") def send_notification_email(url, current_price, threshold_price): """ 发送价格通知邮件。 """ sender_email = "your_email@gmail.com" # 你的邮箱 sender_password = "your_password" # 你的邮箱密码(或授权码) receiver_email = "recipient_email@gmail.com" # 收件人邮箱 subject = "Price Alert!" body = f"The price of the item at {url} has dropped to ${current_price}, which is below your threshold of ${threshold_price}." message = MIMEText(body) message['Subject'] = subject message['From'] = sender_email message['To'] = receiver_email try: with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server: server.login(sender_email, sender_password) server.sendmail(sender_email, receiver_email, message.as_string()) except Exception as e: print(f"Error sending email: {e}") # 示例:监控 Amazon 商品价格 if __name__ == '__main__': product_url = "https://www.amazon.com/dp/B08XXXXXXX" # 替换为实际的 Amazon 商品链接 price_threshold = 100.00 # 价格阈值 while True: amazon_price_tracker(product_url, price_threshold) time.sleep(3600) # 每隔 1 小时检查一次价格
代码详解:
amazon_price_tracker(url, threshold_price) 函数: 接受商品链接和价格阈值作为参数。
页面解析: 使用 BeautifulSoup 解析 HTML 内容,找到价格元素。 注意: Amazon 的页面结构经常变化,需要根据实际页面结构调整选择器。
价格比较: 将提取到的价格与阈值进行比较,如果低于阈值,则调用 send_notification_email 函数发送邮件通知。
send_notification_email(url, current_price, threshold_price) 函数: 使用 smtplib 库发送邮件。 注意: 需要配置正确的邮箱信息。
定时任务: 使用 time.sleep() 函数实现定时任务,每隔一段时间检查一次价格。
3. 优化方向:
使用更稳定的价格元素选择器: 避免因页面结构变化导致爬虫失效。
使用代理 IP: 避免 IP 被封禁。
使用更可靠的通知方式: 例如:短信通知。
使用分布式爬虫: 提高爬取效率,监控更多商品。
集成到自动化平台: 例如:使用 Celery 或 Airflow 实现更复杂的任务调度。
场景描述: 我们需要爬取社交媒体平台(例如:Twitter, Weibo)上特定话题的帖子,并进行情感分析,了解公众对该话题的看法。
1. 爬虫设计:
2. 代码实践:
这里以 Twitter 为例,使用 Tweepy 库进行爬取。
import tweepy import re import pandas as pd from textblob import TextBlob # 用于情感分析 # 替换为你的 Twitter API 凭证 consumer_key = "YOUR_CONSUMER_KEY" consumer_secret = "YOUR_CONSUMER_SECRET" access_token = "YOUR_ACCESS_TOKEN" access_token_secret = "YOUR_ACCESS_TOKEN_SECRET" def twitter_sentiment_analysis(keyword, num_tweets=100): """ 爬取 Twitter 上特定关键词的推文,并进行情感分析。 Args: keyword (str): 搜索关键词。 num_tweets (int): 爬取的推文数量。 Returns: list: 包含推文内容和情感极性的列表。 """ auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth, wait_on_rate_limit=True) # 限制请求频率 results = [] try: tweets = tweepy.Cursor(api.search_tweets, q=keyword, lang="en", tweet_mode='extended').items(num_tweets) for tweet in tweets: text = tweet.full_text # 清洗推文内容 text = re.sub(r"http\S+", "", text) # Remove URLs text = re.sub(r"@\S+", "", text) # Remove mentions text = re.sub(r"#\S+", "", text) # Remove hashtags text = re.sub(r"[^a-zA-Z\s]", "", text) # Remove non-alphabetic characters analysis = TextBlob(text) polarity = analysis.sentiment.polarity # 情感极性,范围 [-1, 1] results.append({ 'text': text, 'polarity': polarity }) except tweepy.TweepyException as e: print(f"Error fetching tweets: {e}") return results # 示例:爬取 "Artificial Intelligence" 关键词的 100 条推文 if __name__ == '__main__': data = twitter_sentiment_analysis("Artificial Intelligence", num_tweets=100) df = pd.DataFrame(data) # 计算平均情感极性 average_polarity = df['polarity'].mean() print(f"Average polarity: {average_polarity}") # 根据情感极性进行分类 def categorize_sentiment(polarity): if polarity > 0.1: return "Positive" elif polarity < -0.1: return "Negative" else: return "Neutral" df['sentiment'] = df['polarity'].apply(categorize_sentiment) print(df['sentiment'].value_counts()) df.to_csv("ai_tweets.csv", index=False)
代码详解:
twitter_sentiment_analysis(keyword, num_tweets) 函数: 接受关键词和推文数量作为参数。
Tweepy 库: 使用 Tweepy 库连接 Twitter API。 注意: 需要注册 Twitter API 账号并获取 API 凭证。
api.search_tweets(): 使用 search_tweets 方法搜索推文。
数据清洗: 使用正则表达式去除推文中的 URL、@mention、#hashtag 和非字母字符。
情感分析: 使用 TextBlob 库进行情感分析,计算情感极性。
情感分类: 根据情感极性将推文分为积极、消极和中性。
平均情感极性计算: 计算平均情感极性,了解整体情感倾向。
3. 优化方向:
使用更强大的情感分析工具: 例如:VADER, BERT。
使用更高级的 NLP 技术: 例如:主题建模,关键词提取,情感词典。
处理语言的多样性: 支持多种语言的情感分析。
考虑上下文信息: 例如:考虑推文的作者、时间、地点等信息。
使用实时数据流: 例如:使用 Twitter Streaming API 实时获取推文。
总结:
通过以上三个案例,我们展示了 Crawl4AI 在不同场景下的应用。 实际项目中,需要根据具体需求进行调整和优化。 关键在于理解爬虫的基本原理,选择合适的工具和技术,并进行充分的测试和验证。 此外,遵守网站的 robots.txt 协议,尊重网站的知识产权,避免对网站造成过大压力,是爬虫开发的基本道德准则。