使用Python构建一个简单的Web爬虫:从入门到实践
在现代的数据驱动世界中,网络爬虫(Web Crawler)是一项非常重要的技术。通过爬虫,我们可以自动地从网页中提取数据,用于数据分析、机器学习训练、市场调研等多种用途。本文将介绍如何使用 Python 构建一个简单的 Web 爬虫,涵盖基本原理、工具选择、代码实现以及一些注意事项。
什么是Web爬虫?
Web爬虫是一种自动化程序,它会按照一定规则访问网页并提取所需信息。搜索引擎如 Google 和 Baidu 就是依靠大规模的爬虫系统来收集互联网上的内容,并建立索引以供用户查询。
一个基本的爬虫流程包括以下几个步骤:
发起请求:向目标网站发送 HTTP 请求获取页面内容。解析响应:分析服务器返回的数据(通常是 HTML),提取有用的信息。存储数据:将提取到的数据保存到文件或数据库中。控制爬取行为:遵循网站的robots.txt
规则,避免对服务器造成过大压力。技术选型
我们将使用以下 Python 库来构建爬虫:
requests:用于发送 HTTP 请求。BeautifulSoup:用于解析 HTML 文档。pandas:用于结构化数据处理和导出。fake_useragent(可选):生成随机 User-Agent,模拟浏览器访问,防止被反爬虫机制拦截。安装这些库可以使用 pip 命令:
pip install requests beautifulsoup4 pandas fake-useragent
注意:某些网站可能启用了 JavaScript 渲染或者复杂的反爬机制,此时应考虑使用 Selenium 或 Scrapy 框架。但本文专注于静态页面的简单抓取。
实战项目:爬取豆瓣电影Top250榜单
我们以 豆瓣电影 Top250 为例,编写一个爬虫程序,抓取每部电影的标题、评分、导演、上映年份等信息,并将其保存为 CSV 文件。
3.1 分析网页结构
打开豆瓣电影 Top250 页面,观察其 HTML 结构。每页显示 25 部电影,分 10 页展示全部 250 部影片。每部电影的信息包含在一个 <div class="item">
中。
使用 Chrome 开发者工具查看 HTML 标签,确定我们需要提取的内容如下:
片名:<span class="title">
导演:<p class="">
中的第一行文本上映年份:位于导演信息中的年份部分评分:<span class="rating_num">
评价人数:<div class="star">
后面的 <span>
中的数字3.2 编写爬虫代码
以下是完整的 Python 爬虫代码:
import requestsfrom bs4 import BeautifulSoupimport pandas as pdfrom fake_useragent import UserAgentimport time# 获取随机User-Agentua = UserAgent()headers = { 'User-Agent': ua.random}def get_movie_data(url): response = requests.get(url, headers=headers) if response.status_code != 200: print(f"Failed to fetch {url}") return [] soup = BeautifulSoup(response.text, 'html.parser') items = soup.find_all('div', class_='item') movies = [] for item in items: title = item.find('span', class_='title').text rating = float(item.find('span', class_='rating_num').text) info = item.find('p', class_='').text.strip().split('\n')[0] year = info.split('(')[-1].replace(')', '') director = info.split(' ')[0].replace('导演:', '') # 查找评价人数 num_ratings = item.find_all('span')[-2].text[:-3] movies.append({ '片名': title, '评分': rating, '导演': director, '年份': year, '评价人数': num_ratings }) return moviesdef crawl_douban_top250(): base_url = "https://movie.douban.com/top250?start={}" all_movies = [] for i in range(0, 250, 25): url = base_url.format(i) print(f"Crawling page: {url}") movies = get_movie_data(url) all_movies.extend(movies) time.sleep(2) # 设置延迟,避免频繁请求 df = pd.DataFrame(all_movies) df.to_csv("douban_top250.csv", index=False, encoding='utf_8_sig') print("数据已保存至 douban_top250.csv")if __name__ == "__main__": crawl_douban_top250()
3.3 代码说明
get_movie_data(url):接收一个页面 URL,返回该页所有电影的信息列表。crawl_douban_top250():遍历 10 个页面,调用get_movie_data()
提取数据,并最终将结果保存为 CSV 文件。time.sleep(2):为了避免触发反爬机制,每次请求之间加入 2 秒延迟。fake_useragent:生成不同的 User-Agent,伪装成不同浏览器访问,提高爬取成功率。3.4 输出结果示例
运行程序后,将在当前目录下生成 douban_top250.csv
文件,部分内容如下:
片名 | 评分 | 导演 | 年份 | 评价人数 |
---|---|---|---|---|
肖申克的救赎 | 9.7 | 弗兰克·德拉邦特 | 1994 | 2645894人 |
霸王别姬 | 9.6 | 陈凯歌 | 1993 | 1584231人 |
阿甘正传 | 9.5 | 罗伯特·泽米吉斯 | 1994 | 1379428人 |
常见问题与解决方案
4.1 反爬虫机制应对策略
设置请求头(User-Agent):使用fake_useragent
动态生成不同浏览器标识。添加请求间隔:使用 time.sleep()
控制请求频率。使用代理 IP:对于高频率访问,可配置代理池轮换 IP 地址。模拟登录:部分网站需要登录才能访问内容,可通过 requests.Session()
维持会话状态。4.2 数据清洗
有时提取的数据中包含多余字符或格式不统一,例如“1994 / 美国”,需进一步清洗。可以使用正则表达式进行处理:
import reyear = re.search(r'\d{4}', info).group()
4.3 异常处理
建议在关键步骤添加异常捕获机制,例如:
try: response = requests.get(url, headers=headers, timeout=10)except requests.exceptions.RequestException as e: print(f"Request error: {e}") continue
本文通过一个实际案例,介绍了使用 Python 构建 Web 爬虫的基本方法,涵盖了请求发送、HTML 解析、数据提取、保存及反爬策略等内容。虽然这个爬虫相对简单,但它为我们理解爬虫工作原理和开发流程提供了很好的基础。
随着你对爬虫技术的深入学习,可以尝试使用更高级的框架如 Scrapy 来构建更大规模、更复杂的爬虫系统,甚至结合分布式任务队列(如 Celery、Scrapy-Redis)实现大规模数据采集。
附录:完整代码 GitHub Gist
你可以在这里查看本项目的完整源码:https://gist.github.com/example/douban-top250-crawler
如果你有任何问题或建议,欢迎留言交流!