当前位置:首页 > 热点

python爬取网站数据并写入excel

用Python抓数据,网站最烦的数据其实不是抓取本身,而是并写抓完之后那一堆乱七八糟的列表和字典。上个月帮朋友弄一个招聘网站的网站数据,爬了3000多条岗位信息,数据控制台里打印出来密密麻麻,并写眼睛都看花了。网站后来直接写进Excel,数据打开表格一拉,并写什么薪资分布、网站公司规模,数据一目了然。并写所以这篇东西就讲一个完整流程:从请求网页到把数据落进Excel。网站

先装两个库。数据requests负责发请求,并写openpyxl负责写Excel。命令行里pip install requests openpyxl就行。别用xlwt,那个只支持老版.xls,行数一多就崩。openpyxl虽然写入速度不算快,但胜在稳定,格式控制也够用。

假设目标是一个图书网站,列表页结构简单,每本书有标题、价格、评分三个字段。先拿一页试试水:

import requests from openpyxl import Workbook url = "https://example.com/books?page=1" headers = { "User-Agent": "Mozilla/5.0"} resp = requests.get(url, headers=headers) print(resp.status_code) 

200就继续。接下来解析HTML。BeautifulSoup或者lxml都行,我用lxml,快一些。找到列表容器,遍历每个条目,把文本抠出来。这里有个坑:价格字段经常带货币符号和空格,评分可能是“4.5星”这种混合文本。写个清洗函数,用正则把数字提出来。

from lxml import etree import re html = etree.HTML(resp.text) items = html.xpath('//div[@class="book-item"]') data = [] for item in items: title = item.xpath('.//h3/text()')[0].strip() price_raw = item.xpath('.//span[@class="price"]/text()')[0] price = float(re.search(r'[\d.]+', price_raw).group()) rating_raw = item.xpath('.//span[@class="rating"]/text()')[0] rating = float(re.search(r'[\d.]+', rating_raw).group()) data.append([title, price, rating]) 

一页跑通之后,翻页就是改URL参数的事。但别傻乎乎地写while True,很多网站有翻页上限,或者最后一页返回空列表。加个判断:如果items为空,直接break。另外记得加time.sleep(1),不然请求发太快容易被封IP。我试过不加延迟连续请求50页,结果第30页开始返回403,换IP才恢复。

数据攒齐了,写Excel。openpyxl的基本操作:创建Workbook,选中活动sheet,用append逐行写入。表头单独写一行,加粗一下方便看。

wb = Workbook() ws = wb.active ws.title = "图书数据" ws.append(["书名", "价格", "评分"]) for row in data: ws.append(row) wb.save("books.xlsx") 

跑完打开文件,3000行数据整整齐齐。但有个问题:价格列显示成“45.0”而不是“45.00”,评分列有的显示“4”而不是“4.0”。这是Excel的单元格格式问题,跟Python写入无关。在openpyxl里可以设置number_format:

for cell in ws['B'][1:]: cell.number_format = '0.00' for cell in ws['C'][1:]: cell.number_format = '0.0' 

另外,如果数据量超过几万行,openpyxl的内存占用会明显上升。有个取巧的办法:用write_only模式,边抓边写,不把所有数据堆在内存里。但那样就不能回头改格式了,得提前想好列宽和对齐。我一般数据量低于5万行就直接普通模式,省事。

最后提一个实际遇到的问题:有些网站返回的HTML里,数字用了全角字符,比如“4.5”。正则匹配不到,得先做全角转半角。写个转换函数,用ord判断范围,或者直接str.maketrans。这种细节不处理,写进Excel就是一堆文本格式的数字,排序功能直接废掉。

整个流程跑下来,代码不到80行。核心就三件事:请求、解析、写入。难点不在语法,在于每个网站的结构差异和反爬策略。遇到动态加载的页面,requests拿不到数据,那就得换selenium或者直接分析XHR请求。那是另一个话题了。

分享到: