使用Python实现一个简单的Web爬虫

今天 2阅读

在当今互联网时代,数据是无处不在的。从社交媒体到电子商务网站,各种信息都隐藏在网络中等待被挖掘。为了获取这些数据,我们经常使用网络爬虫(Web Crawler)技术来自动抓取网页内容。本文将介绍如何使用Python编写一个简单的Web爬虫,并展示其基本原理和实际应用。

我们将使用requests库来发送HTTP请求,并用BeautifulSoup解析HTML文档。最后,我们还会将爬取的数据保存为CSV文件。


准备工作

1. 安装所需库

首先确保你已经安装了以下Python库:

pip install requests beautifulsoup4 lxml pandas
requests:用于发送HTTP请求。beautifulsoup4:用于解析HTML文档。lxml:作为BeautifulSoup的解析器,速度快。pandas:用于数据处理与保存。

爬虫的基本结构

一个基础的爬虫通常包括以下几个步骤:

发送HTTP请求获取网页内容;解析HTML内容,提取目标数据;存储或处理提取到的数据;遵守网站的robots.txt规则,避免频繁访问造成负担。

实战:爬取豆瓣电影Top250榜单

我们将以豆瓣电影Top250为例,爬取每部电影的名称、评分、导演、年份、国家和类型等信息。

1. 发送请求并获取页面内容

import requestsfrom bs4 import BeautifulSoupimport timeimport randomdef get_html(url):    headers = {        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0 Safari/537.36'    }    try:        response = requests.get(url, headers=headers)        if response.status_code == 200:            return response.text        else:            print(f"请求失败,状态码:{response.status_code}")            return None    except Exception as e:        print("请求出错:", e)        return None

2. 解析HTML并提取电影信息

def parse_html(html):    soup = BeautifulSoup(html, 'lxml')    items = soup.find_all('div', class_='item')    movies = []    for item in items:        rank = item.find('em').text.strip()        title = item.find('span', class_='title').text.strip()        rating = item.find('span', class_='rating_num').text.strip()        info = item.find('div', class_='bd').p.text.strip().split('\n')        director_and_year = info[0].strip().replace(' ', '').split('...')        director = director_and_year[0][3:]  # 去掉导演前面的“导演:”        year = director_and_year[-1]        country_genre = info[1].strip().split('/')        country = country_genre[0]        genre = '/'.join(country_genre[1:]).strip()        movie_data = {            '排名': rank,            '片名': title,            '评分': rating,            '导演': director,            '年份': year,            '国家': country,            '类型': genre        }        movies.append(movie_data)    return movies

3. 爬取所有页面(分页)

豆瓣Top250是分页的,每页显示25条记录,共10页。

def crawl_douban_top250():    base_url = "https://movie.douban.com/top250?start="    all_movies = []    for i in range(0, 250, 25):        url = base_url + str(i)        html = get_html(url)        if html:            movies = parse_html(html)            all_movies.extend(movies)            print(f"已爬取第 {i // 25 + 1} 页,共 {len(movies)} 条电影数据")            time.sleep(random.uniform(1, 3))  # 模拟人类访问间隔        else:            break    return all_movies

4. 保存为CSV文件

import pandas as pddef save_to_csv(data, filename='douban_top250.csv'):    df = pd.DataFrame(data)    df.to_csv(filename, index=False, encoding='utf-8-sig')    print(f"数据已成功保存至 {filename}")

5. 主函数调用

if __name__ == '__main__':    data = crawl_douban_top250()    save_to_csv(data)

完整代码整合

以下是完整的Python脚本:

import requestsfrom bs4 import BeautifulSoupimport timeimport randomimport pandas as pddef get_html(url):    headers = {        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0 Safari/537.36'    }    try:        response = requests.get(url, headers=headers)        if response.status_code == 200:            return response.text        else:            print(f"请求失败,状态码:{response.status_code}")            return None    except Exception as e:        print("请求出错:", e)        return Nonedef parse_html(html):    soup = BeautifulSoup(html, 'lxml')    items = soup.find_all('div', class_='item')    movies = []    for item in items:        rank = item.find('em').text.strip()        title = item.find('span', class_='title').text.strip()        rating = item.find('span', class_='rating_num').text.strip()        info = item.find('div', class_='bd').p.text.strip().split('\n')        director_and_year = info[0].strip().replace(' ', '').split('...')        director = director_and_year[0][3:]  # 去掉导演前面的“导演:”        year = director_and_year[-1]        country_genre = info[1].strip().split('/')        country = country_genre[0]        genre = '/'.join(country_genre[1:]).strip()        movie_data = {            '排名': rank,            '片名': title,            '评分': rating,            '导演': director,            '年份': year,            '国家': country,            '类型': genre        }        movies.append(movie_data)    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 + str(i)        html = get_html(url)        if html:            movies = parse_html(html)            all_movies.extend(movies)            print(f"已爬取第 {i // 25 + 1} 页,共 {len(movies)} 条电影数据")            time.sleep(random.uniform(1, 3))  # 模拟人类访问间隔        else:            break    return all_moviesdef save_to_csv(data, filename='douban_top250.csv'):    df = pd.DataFrame(data)    df.to_csv(filename, index=False, encoding='utf-8-sig')    print(f"数据已成功保存至 {filename}")if __name__ == '__main__':    data = crawl_douban_top250()    save_to_csv(data)

注意事项与合法性

虽然网络爬虫是一个非常强大的工具,但我们在使用时也需要注意以下几点:

遵守Robots协议:检查目标网站根目录下的robots.txt文件,确认是否允许爬虫访问相关路径。设置合理的请求频率:避免对服务器造成过大压力,使用随机延迟。尊重版权和隐私:不要爬取涉及用户隐私或其他受保护的内容。使用合法的User-Agent:模拟真实浏览器行为,减少被封IP的风险。

总结

本文通过一个完整的示例,演示了如何使用Python构建一个简单的Web爬虫程序。我们使用了requests发起请求,BeautifulSoup解析HTML,最后使用pandas保存数据为CSV格式。整个过程展示了爬虫的基本流程和技术要点。

随着经验的积累,你可以进一步扩展这个爬虫系统,比如添加代理IP支持、多线程并发、数据库存储等功能,甚至构建一个完整的数据采集平台。

如果你对网络爬虫感兴趣,欢迎继续深入学习Scrapy框架、Selenium自动化测试等更高级的技术!


附录:运行结果示例

运行上述程序后,将在当前目录生成一个名为douban_top250.csv的文件,内容如下:

排名片名评分导演年份国家类型
1肖申克的救赎9.7弗兰克·德拉邦特1994美国剧情 / 犯罪
2霸王别姬9.6陈凯歌1993中国大陆 / 香港剧情 / 爱情 / 同性

如需获取完整源码,请复制以上代码粘贴至.py文件中即可运行。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第22996名访客 今日有16篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!