用BeautifulSoup写网络爬虫,其实没那么难
平时想查点数据,比如电影评分、商品价格,一个个打开网页太费劲。写个脚本自动抓,省时省力。Python里有个叫BeautifulSoup的库,专门处理网页内容,配合requests,抓数据就像在超市拿货一样顺手。
先装好工具包
用pip装两个东西就行:requests负责发请求拿网页,BeautifulSoup负责解析网页结构。
pip install requests beautifulsoup4拿到网页源码
比如你想看看豆瓣电影Top250的片名,先用requests把页面拉下来。
import requests
url = 'https://movie.douban.com/top250'
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)
html = response.text注意加headers,不然有些网站会拒绝访问,就像进门不打招呼容易被拦下。
用BeautifulSoup读网页
把拿到的html交给BeautifulSoup,它会帮你把杂乱的标签整理成树状结构,方便查找。
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')'html.parser'是内置解析器,不用额外装,对付普通网页够用了。
找你要的数据
打开浏览器开发者工具,看到每部电影都在<li>标签里,片名在<span class="title">里面。直接用find_all就能批量提取。
titles = soup.find_all('span', class_='title')
for title in titles:
print(title.get_text())class_后面加个下划线是Python语法要求,避免和关键字冲突。get_text()只拿文字,不要标签。
过滤只需要的标题
发现每个电影有两个title,第一个是中文名。可以限制只取第一个。
movie_names = []
for title in titles:
if title.get_text().endswith('/') == False:
movie_names.append(title.get_text())
movie_names = movie_names[::2] # 每两一个取一个或者更干脆,在find_all里加限制:
titles = soup.find_all('span', class_='title', limit=250)
chinese_titles = [t.get_text() for i, t in enumerate(titles) if i % 2 == 0]保存数据到本地
抓下来的数据,存成文本或CSV,以后还能用。
with open('douban_top250.txt', 'w', encoding='utf-8') as f:
for name in chinese_titles:
f.write(name + '\n')文件打开记得加encoding='utf-8',不然中文乱码,看着像天书。
遇到反爬怎么办
有些网站加载的是JavaScript动态内容,requests拿不到真实数据。这时候得换Selenium或者找API接口。BeautifulSoup适合静态页面,别硬刚动态站。
还有些网站会封IP,加time.sleep(1)放慢频率,别一口气猛刷,像人慢慢翻页才自然。
小项目练手建议
新手可以从天气预报、新闻标题、小说章节开始练。比如每天自动抓一次天气,微信推给自己,比看APP还快一步。熟练了再上大项目,别一上来就想抓全网商品比价,容易踩坑。
BeautifulSoup不是万能的,但它足够简单,适合大多数日常抓取需求。工具不在多,用熟才是王道。