目录
科技新闻是我们了解最新科技动态、发现新兴科技趋势的重要来源。本文将详细介绍如何使用Python编写网络爬虫,从科技新闻网站获取最新科技新闻。我们将爬取首页上的新闻信息。
1. 准备工作
在开始编写爬虫之前,需要安装以下Python库:
requests
:用于发送HTTP请求。beautifulsoup4
:用于解析HTML文档。pandas
:用于操作和保存数据。
pip install requests beautifulsoup4 pandas
2. 分析目标网站
在编写爬虫之前,需要分析目标网站的HTML结构,以确定需要提取的数据。查看网页源代码,我们可以发现新闻信息位于一个名为<table>
的表格中。表格中的每个<tr>
元素都包含一条新闻的信息,如标题、作者、发布时间等。我们希望提取以下信息:
- 标题
- 链接
- 作者
- 发布时间
- 评论数量
- 得分
3. 编写爬虫
根据以上分析,我们可以编写一个简单的爬虫来提取科技新闻信息。首先,导入所需的库,并发送HTTP请求获取网页内容。
import requests
from bs4 import BeautifulSoup
import pandas as pd
url = 'https://news.ycombinator.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
response = requests.get(url, headers=headers)
接下来,使用beautifulsoup4
解析HTML文档,并提取科技新闻信息。
soup = BeautifulSoup(response.text, 'html.parser')
news_table = soup.find('table', class_='itemlist')
news_rows = news_table.find_all('tr', class_='athing')
news_data = []
for news_row in news_rows:
title = news_row.find('a', class_='storylink').text.strip()
link = news_row.find('a', class_='storylink')['href']
info_row = news_row.find_next_sibling('tr')
author = info_row.find('a', class_='hnuser').text.strip() if info_row.find('a', class_='hnuser') else None
age = info_row.find('span', class_='age').text.strip() if info_row.find('span', class_='age') else None
comments = info_row.find_all('a')[-1].text.strip() if info_row.find_all('a') else None
comments = int(comments.split()[0]) if comments and comments != 'discuss' else 0
score = info_row.find('span', class_='score').text.strip() if info_row.find('span', class_='score') else None
score = int(score.split()[0]) if score else 0
news_data.append([title, link, author, age, comments, score])
将提取的数据保存到pandas.DataFrame
对象中,并将其导出为CSV文件。
columns = ['Title', 'Link', 'Author', 'Age', 'Comments', 'Score']
df = pd.DataFrame(news_data, columns=columns)
df.to_csv('hacker_news.csv', index=False)
至此,我们已经成功提取了科技新闻信息,并将其保存到了CSV文件中。
4. 优化和扩展
我们可以对上面的爬虫代码进行一些优化和扩展,以提高其可读性、易用性和功能。
- 封装成函数:将爬虫代码封装成一个函数,以便在其他项目中重用。
def crawl_hacker_news(url, headers):
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
news_table =soup.find('table', class_='itemlist')
news_rows = news_table.find_all('tr', class_='athing')
news_data = []
for news_row in news_rows:
title = news_row.find('a', class_='storylink').text.strip()
link = news_row.find('a', class_='storylink')['href']
info_row = news_row.find_next_sibling('tr')
author = info_row.find('a', class_='hnuser').text.strip() if info_row.find('a', class_='hnuser') else None
age = info_row.find('span', class_='age').text.strip() if info_row.find('span', class_='age') else None
comments = info_row.find_all('a')[-1].text.strip() if info_row.find_all('a') else None
comments = int(comments.split()[0]) if comments and comments != 'discuss' else 0
score = info_row.find('span', class_='score').text.strip() if info_row.find('span', class_='score') else None
score = int(score.split()[0]) if score else 0
news_data.append([title, link, author, age, comments, score])
return news_data
url = 'https://news.ycombinator.com/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
news_data = crawl_hacker_news(url, headers)
columns = ['Title', 'Link', 'Author', 'Age', 'Comments', 'Score']
df = pd.DataFrame(news_data, columns=columns)
df.to_csv('hacker_news.csv', index=False)
2.抓取多页数据:对于分页的网站,可以在函数中添加参数来控制抓取的页数。
def crawl_hacker_news(pages, headers):
all_news_data = []
base_url = 'https://news.ycombinator.com/'
for page in range(1, pages + 1):
url = f'{base_url}news?p={page}'
news_data = crawl_hacker_news_page(url, headers)
all_news_data.extend(news_data)
return all_news_data
news_data = crawl_hacker_news(pages=3, headers=headers)
3.处理异常:在请求和解析过程中,可能会出现网络错误、解析错误等异常情况。为避免程序意外终止,可以添加异常处理代码。
def crawl_hacker_news_page(url, headers):
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
except requests.RequestException as e:
print(f"Error requesting {url}: {e}")
return []
try:
soup = BeautifulSoup(response.text, 'html.parser')
news_data = parse_news_data(soup)
except Exception as e:
print(f"Error parsing {url}: {e}")
return []
return news_data
4.使用代理:为避免请求过于频繁导致IP被封,可以使用代理服务器发送请求。
proxies = {
'http': 'http://proxy.example.com:8080',
'https': 'https://proxy.example.com:8080'
}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
response = requests.get(url, headers=headers, proxies=proxies)
通过以上优化和扩展,我们的爬虫更加健壮和功能丰富。希望本文能帮助你学会如何使用Python编写网络爬虫,从科技新闻网站获取最新科技新闻