使用 Python 实现一个简单的 Web 爬虫
在当今数据驱动的世界中,网络爬虫(Web Crawler) 是获取互联网信息的重要工具。它可以帮助我们从网页中提取结构化数据,用于数据分析、机器学习、市场研究等多个领域。本文将介绍如何使用 Python 编写一个简单的 Web 爬虫,并通过实际代码演示其工作原理。
我们将使用以下技术栈:
Requests:发送 HTTP 请求并获取网页内容。BeautifulSoup:解析 HTML 并提取所需数据。CSV:保存爬取的数据为本地文件。什么是 Web 爬虫?
Web 爬虫是一种自动抓取网页内容的程序。它按照一定的规则访问网页,提取页面中的超链接,然后递归地继续访问这些链接,从而实现对整个网站或部分页面的遍历和数据采集。
准备工作
在开始编写爬虫之前,请确保你已经安装了以下 Python 库:
pip install requests beautifulsoup4
如果你打算保存数据到 CSV 文件,标准库 csv
已经足够使用。
构建第一个 Web 爬虫
我们的目标是爬取 https://books.toscrape.com/ 这个测试网站上的书籍信息,包括书名、价格和评分等。
3.1 发送请求与解析 HTML
首先,我们来获取首页的内容并解析出所有书籍的链接。
import requestsfrom bs4 import BeautifulSoupurl = "https://books.toscrape.com/"response = requests.get(url)# 检查是否成功获取页面if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') # 查找所有书籍的链接 books = soup.find_all('h3') book_links = [book.find('a')['href'] for book in books] print("书籍链接:", book_links)else: print(f"无法访问网站,状态码:{response.status_code}")
这段代码使用 requests
获取网页内容,并使用 BeautifulSoup
解析 HTML,提取出所有书籍的链接。
3.2 提取书籍详细信息
接下来,我们逐个访问每个书籍页面,提取更多信息。
def extract_book_info(book_url): full_url = f"https://books.toscrape.com/{book_url}" response = requests.get(full_url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') title = soup.find('h1').text price = soup.find('p', class_='price_color').text rating = soup.find('p', class_='star-rating')['class'][1] # 获取星级 return { 'title': title, 'price': price, 'rating': rating } else: print(f"无法访问书籍页面:{full_url}") return None# 测试提取一本书的信息book_data = extract_book_info(book_links[0])print(book_data)
上述函数 extract_book_info
接收书籍页面的相对 URL,构造完整地址后访问页面并提取标题、价格和评分。
3.3 将数据保存为 CSV 文件
我们可以将爬取到的所有书籍信息保存到 CSV 文件中以便后续处理。
import csvall_books = []for link in book_links: book_info = extract_book_info(link) if book_info: all_books.append(book_info)# 写入 CSV 文件with open('books.csv', mode='w', newline='', encoding='utf-8') as file: writer = csv.DictWriter(file, fieldnames=['title', 'price', 'rating']) writer.writeheader() writer.writerows(all_books)print("书籍信息已保存至 books.csv")
运行以上代码后,当前目录下将生成一个名为 books.csv
的文件,内容如下:
title,price,ratingA Light in the Attic,£51.77,FiveTipping the Velvet,£53.74,ThreeSoumission,£50.10,One...
扩展功能:支持翻页爬取
目前我们只爬取了首页的书籍。为了爬取整个网站的内容,我们需要识别“下一页”按钮的链接并循环爬取。
def get_next_page(soup): next_link = soup.find('li', class_='next') if next_link: return next_link.find('a')['href'] return Nonecurrent_url = urlwhile current_url: response = requests.get(current_url) if response.status_code != 200: break soup = BeautifulSoup(response.text, 'html.parser') books = soup.find_all('h3') book_links = [book.find('a')['href'] for book in books] for link in book_links: book_info = extract_book_info(link) if book_info: all_books.append(book_info) next_page = get_next_page(soup) if next_page: current_url = f"https://books.toscrape.com/{next_page}" else: current_url = None# 最后再写一次 CSVwith open('all_books.csv', mode='w', newline='', encoding='utf-8') as file: writer = csv.DictWriter(file, fieldnames=['title', 'price', 'rating']) writer.writeheader() writer.writerows(all_books)print("全部书籍信息已保存至 all_books.csv")
注意事项与法律问题
虽然 Web 爬虫是一个强大的工具,但在使用时需注意以下几点:
尊重 robots.txt:检查目标网站根目录下的robots.txt
文件,了解哪些路径允许爬虫访问。控制请求频率:避免短时间内发送大量请求,以免对服务器造成压力。设置 User-Agent:模拟浏览器访问,避免被封锁。遵守法律法规:未经授权不得爬取受版权保护的数据。总结
本文介绍了如何使用 Python 构建一个简单的 Web 爬虫,涵盖请求发送、HTML 解析、数据提取与保存等关键步骤。我们还实现了分页爬取功能,并讨论了使用爬虫时需要注意的伦理和法律问题。
Web 爬虫是数据采集的基础技能之一,掌握它可以为你打开通往大数据世界的大门。随着经验的积累,你可以进一步探索使用 Selenium、Scrapy 等更高级的爬虫框架,以应对更复杂的网页结构和反爬机制。
附录:完整源码
import requestsfrom bs4 import BeautifulSoupimport csvdef extract_book_info(book_url): full_url = f"https://books.toscrape.com/{book_url}" response = requests.get(full_url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') title = soup.find('h1').text price = soup.find('p', class_='price_color').text rating = soup.find('p', class_='star-rating')['class'][1] # 获取星级 return { 'title': title, 'price': price, 'rating': rating } else: print(f"无法访问书籍页面:{full_url}") return Nonedef get_next_page(soup): next_link = soup.find('li', class_='next') if next_link: return next_link.find('a')['href'] return Noneurl = "https://books.toscrape.com/"current_url = urlall_books = []while current_url: response = requests.get(current_url) if response.status_code != 200: break soup = BeautifulSoup(response.text, 'html.parser') books = soup.find_all('h3') book_links = [book.find('a')['href'] for book in books] for link in book_links: book_info = extract_book_info(link) if book_info: all_books.append(book_info) next_page = get_next_page(soup) if next_page: current_url = f"https://books.toscrape.com/{next_page}" else: current_url = None# 写入 CSV 文件with open('all_books.csv', mode='w', newline='', encoding='utf-8') as file: writer = csv.DictWriter(file, fieldnames=['title', 'price', 'rating']) writer.writeheader() writer.writerows(all_books)print("全部书籍信息已保存至 all_books.csv")
如需进一步学习,建议阅读官方文档:
Requests 官方文档BeautifulSoup 文档