百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

Python爬虫进阶教程(五):数据存储

bigegpt 2024-10-21 03:48 2 浏览

本篇主要介绍,爬取html数据后,将html的正文内容存储为json或csv格式。

json格式存储

选定要爬取的网站后,我们利用之前学过的内容,如:Beautiful Soup、xpath等方式解析,来获取我们希望得到的内容。

获取数据

首先使用urllib访问页面https://www.lagou.com/zhaopin/Python/?labelWords=label

获取html内容,代码如下:

from urllib import request
?
try:
 url = 'https://www.lagou.com/zhaopin/Python/?labelWords=label'
 header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}
 req = request.Request(url, headers=header)
 response = request.urlopen(req).read().decode('utf-8')
except request.URLError as e:
 if hasattr(e, 'reason'):
 print(e.reason)
 elif hasattr(e, 'code'):
 print(e.code)

通过上面的代码获取了html内容,接下来就要分析html来提取我们需要的内容了。

打开拉钩页面,使用ctrl+ F12打开火狐浏览器工具,可以看到我们想要获取的内容,职位、工作地点、薪资、发布的公司等信息都在一个div中,如下图:

下一步我们就使用之前介绍过的Beautiful Soup获取这个div内容,同时也可以获取我们需要的内容,通过工具我们可以看到我们需要的内容所在的标签,见下图:

# 生成soup实例
soup = BeautifulSoup(response, 'lxml')
# 获取class=‘list_item_top’的div标签
divlist = soup.find_all('div', class_='list_item_top')
# 定义空列表
content = []
# 通过循环,获取需要的内容
for list in divlist:
 # 职位名称
 job_name = list.find('h3').string
 # 职位详细页面
 link = list.find('a', class_="position_link").get('href')
 # 招聘的公司
 company = list.find('div', class_='company_name').find('a').string
 # 薪水
 salary = list.find('span', class_='money').string
 print(job_name, company, salary, link)
 content.append({'job': job_name, 'company': company, 'salary': salary, 'link': link})

都是通过Beautiful Soup的方法获取的内容,如果不懂,大家可以翻翻之前的工具篇。输出的内容如下:

Python 开发工程师 还呗-智能信贷领先者 10k-15k https://www.lagou.com/jobs/2538412.html
Python开发工程师 天玑科技 10K-20K https://www.lagou.com/jobs/3608088.html
Python 兜乐科技 6k-12k https://www.lagou.com/jobs/4015725.html
Python 妙计旅行 8k-16k https://www.lagou.com/jobs/3828627.html
Python工程师 洋钱罐 25k-35k https://www.lagou.com/jobs/3852092.html
Python软件开发工程师 深信服科技集团 15k-20k https://www.lagou.com/jobs/4009780.html
Python开发 问卷网@爱调研 15k-25k https://www.lagou.com/jobs/3899604.html
Python Veeva 25k-35k https://www.lagou.com/jobs/3554732.html
python工程师 多麦 10k-20k https://www.lagou.com/jobs/3917781.html
python工程师 北蚁 8k-12k https://www.lagou.com/jobs/3082699.html
python研发工程师 数美 15k-30k https://www.lagou.com/jobs/3684787.html
python开发工程师 紫川软件 12k-19k https://www.lagou.com/jobs/3911802.html
python开发工程师 老虎证券 20k-40k https://www.lagou.com/jobs/3447959.html
Python开发 印孚瑟斯 10k-20k https://www.lagou.com/jobs/3762196.html
Python工程师 江苏亿科达 10k-20k https://www.lagou.com/jobs/3796922.html

好,数据有了,就差存储了。

数据存储(json)

python通过json模块对数据进行编码和解码。编码过程是,通过json模块的dumps和dump对数据进行python对象到json对象的转换,解码过程是,通过json模块的loads和load对数据进行json对象到python对象的转换。

编码

dump将python 对象序列化为一个JSON格式的流,存储到文件,转换时类型变化如下:

json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

dumps将obj序列化为JSON格式的str

json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

解码

load对Python对象进行反序列化,可以从文件读取

json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

oads对Python对象进行反序列化

json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

了解了json操作,现在就可以把之前获取的拉钩数据存储为json了,见下面代码:

with open('lagou.json', 'w') as fp:
 # indent表示缩进,如果输入这个参数,json的数据会按照找个缩进存储
 # 如果不设置,则按最紧凑方式存储
 json.dump(content, fp=fp, indent=4)

好了,存储为json格式就说到这里了。完整代码如下:

import json
from bs4 import BeautifulSoup
from urllib import request
?
try:
 url = 'https://www.lagou.com/zhaopin/Python/?labelWords=label'
 header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}
 req = request.Request(url, headers=header)
 response = request.urlopen(req).read().decode('utf-8')
except request.URLError as e:
 if hasattr(e, 'reason'):
 print(e.reason)
 elif hasattr(e, 'code'):
 print(e.code)
?
# 生成soup实例
soup = BeautifulSoup(response, 'lxml')
# 获取class=‘list_item_top’的div标签
divlist = soup.find_all('div', class_='list_item_top')
# 定义空列表
content = []
# 通过循环,获取需要的内容
for list in divlist:
 # 职位名称
 job_name = list.find('h3').string
 # 职位详细页面
 link = list.find('a', class_="position_link").get('href')
 # 招聘的公司
 company = list.find('div', class_='company_name').find('a').string
 # 薪水
 salary = list.find('span', class_='money').string
 print(job_name, company, salary, link)
 content.append({'job': job_name, 'company': company, 'salary': salary, 'link': link})
?
with open('lagou.json', 'w') as fp:
 # indent表示缩进,如果输入这个参数,json的数据会按照找个缩进存储
 # 如果不设置,则按最紧凑方式存储
 json.dump(content, fp=fp, indent=4)

csv格式存储

所谓的CSV(Comma Separated Values)格式是电子表格和数据库最常用的导入和导出格式。

python的csv模块实现类以csv格式读取和写入表格数据。它允许程序员说,“以Excel的格式编写这些数据”,或者“从Excel生成的文件中读取数据”,而不知道Excel使用的CSV格式的详细信息。程序员还可以描述其他应用程序所理解的CSV格式,或者定义他们自己的专用CSV格式。

写数据到csv文件中

# -*- coding: utf-8 -*-
import csv
?
# 定义第一行
header = ['id', 'name']
# 2条数据
d1 = [1, "xiaoming"]
d2 = [2, "lucy"]
?
# 打开csv文件,newline作用是去掉空行,不加结果之间会有一个空行
with open('test.csv', 'w', newline='') as f:
 # 建立写入对象
 writer = csv.writer(f)
 # 写入数据
 writer.writerow(header)
 writer.writerow(d1)
 writer.writerow(d2)

生成的csv文件内容如下:

id,name
1,xiaoming
2,lucy

写字典到csv文件

import csv
?
with open('names.csv', 'w', newline='') as csvfile:
 # 定义名称,也就是header
 fieldnames = ['first_name', 'last_name']
 # 直接将fieldnames写入,写入字典使用DictWriter方法
 writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
 # 调用writeheader方法加入header
 writer.writeheader()
 # 写入字典数据
 writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
 writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
 writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

获取的csv文件内容如下:

first_name,last_name
Baked,Beans
Lovely,Spam
Wonderful,Spam

读取csv文件

import csv
with open('xingming.csv', 'r') as f:
 # 创建reader对象
 reader = csv.reader(f)
 # reader是可迭代对象,可以通过for循环获取内容
 for row in reader:
 print(row)

结果如下:

['id', 'name']
['1', 'xiaoming']
['2', 'lucy']

以字典形式读入csv文件

import csv
with open('names.csv', 'r') as f:
 # 定义字典阅读对象
 reader = csv.DictReader(f)
 # 打印第一行名称
 print(reader.fieldnames)
 # 循环打印字典内容
 for row in reader:
 print(row['first_name'], row['last_name'])

输出结果:

['first_name', 'last_name']
Baked Beans
Lovely Spam
Wonderful Spam

所以爬取拉钩网数据,如果存储到csv文件的代码如下:

import csv
from bs4 import BeautifulSoup
from urllib import request
?
try:
 url = 'https://www.lagou.com/zhaopin/Python/?labelWords=label'
 header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}
 req = request.Request(url, headers=header)
 response = request.urlopen(req).read().decode('utf-8')
except request.URLError as e:
 if hasattr(e, 'reason'):
 print(e.reason)
 elif hasattr(e, 'code'):
 print(e.code)
?
# 生成soup实例
soup = BeautifulSoup(response, 'lxml')
# 获取class=‘list_item_top’的div标签
divlist = soup.find_all('div', class_='list_item_top')
# 定义空列表
content = []
# 通过循环,获取需要的内容
for list in divlist:
 # 职位名称
 job_name = list.find('h3').string
 # 职位详细页面
 link = list.find('a', class_="position_link").get('href')
 # 招聘的公司
 company = list.find('div', class_='company_name').find('a').string
 # 薪水
 salary = list.find('span', class_='money').string
 # print(job_name, company, salary, link)
 content.append({'job': job_name, 'company': company, 'salary': salary, 'link': link})
?
with open('lagou.csv', 'a', newline='') as f:
 # 定义header
 fieldnames = ['job', 'company', 'salary', 'link']
 # 通过DictWriter方法写入字典
 writer = csv.DictWriter(f, fieldnames=fieldnames)
 # 写入header
 writer.writeheader()
 # 循环获取content内容,写入csv文件
 for row in content:
 writer.writerow(row)

获取的数据如下:

突然发现今天的例子还是存为csv格式合适,找工作新技能,你get了吗~!

相关推荐

Java 泛型大揭秘:类型参数、通配符与最佳实践

引言在编程世界中,代码的可重用性和可维护性是至关重要的。为了实现这些目标,Java5引入了一种名为泛型(Generics)的强大功能。本文将详细介绍Java泛型的概念、优势和局限性,以及如何在...

K8s 的标签与选择器:流畅运维的秘诀

在Kubernetes的世界里,**标签(Label)和选择器(Selector)**并不是最炫酷的技术,但却是贯穿整个集群管理与运维流程的核心机制。正是它们让复杂的资源调度、查询、自动化运维变得...

哈希Hash算法:原理、应用(哈希算法 知乎)

原作者:Linux教程,原文地址:「链接」什么是哈希算法?哈希算法(HashAlgorithm),又称为散列算法或杂凑算法,是一种将任意长度的数据输入转换为固定长度输出值的数学函数。其输出结果通常被...

C#学习:基于LLM的简历评估程序(c# 简历)

前言在pocketflow的例子中看到了一个基于LLM的简历评估程序的例子,感觉还挺好玩的,为了练习一下C#,我最近使用C#重写了一个。准备不同的简历:image-20250528183949844查...

55顺位,砍41+14+3!季后赛也成得分王,难道他也是一名球星?

雷霆队最不可思议的新星:一个55号秀的疯狂逆袭!你是不是也觉得NBA最底层的55号秀,就只能当饮水机管理员?今年的55号秀阿龙·威金斯恐怕要打破你的认知了!常规赛阶段,这位二轮秀就像开了窍的天才,直接...

5分钟读懂C#字典对象(c# 字典获取值)

什么是字典对象在C#中,使用Dictionary类来管理由键值对组成的集合,这类集合被称为字典。字典最大的特点就是能够根据键来快速查找集合中的值,其键的定义不能重复,具有唯一性,相当于数组索引值,字典...

c#窗体传值(c# 跨窗体传递数据)

在WinForm编程中我们经常需要进行俩个窗体间的传值。下面我给出了两种方法,来实现传值一、在输入数据的界面中定义一个属性,供接受数据的窗体使用1、子窗体usingSystem;usingSyst...

C#入门篇章—委托(c#委托的理解)

C#委托1.委托的定义和使用委托的作用:如果要把方法作为函数来进行传递的话,就要用到委托。委托是一个类型,这个类型可以赋值一个方法的引用。C#的委托通过delegate关键字来声明。声明委托的...

C#.NET in、out、ref详解(c#.net framework)

简介在C#中,in、ref和out是用于修改方法参数传递方式的关键字,它们决定了参数是按值传递还是按引用传递,以及参数是否必须在传递前初始化。基本语义对比修饰符传递方式可读写性必须初始化调用...

C#广义表(广义表headtail)

在C#中,广义表(GeneralizedList)是一种特殊的数据结构,它是线性表的推广。广义表可以包含单个元素(称为原子),也可以包含另一个广义表(称为子表)。以下是一个简单的C#广义表示例代...

「C#.NET 拾遗补漏」04:你必须知道的反射

阅读本文大概需要3分钟。通常,反射用于动态获取对象的类型、属性和方法等信息。今天带你玩转反射,来汇总一下反射的各种常见操作,捡漏看看有没有你不知道的。获取类型的成员Type类的GetMembe...

C#启动外部程序的问题(c#怎么启动)

IT&OT的深度融合是智能制造的基石。本公众号将聚焦于PLC编程与上位机开发。除理论知识外,也会结合我们团队在开发过程中遇到的具体问题介绍一些项目经验。在使用C#开发上位机时,有时会需要启动外部的一些...

全网最狠C#面试拷问:这20道题没答出来,别说你懂.NET!

在竞争激烈的C#开发岗位求职过程中,面试是必经的一道关卡。而一场高质量的面试,不仅能筛选出真正掌握C#和.NET技术精髓的人才,也能让求职者对自身技术水平有更清晰的认知。今天,就为大家精心准备了20道...

C#匿名方法(c#匿名方法与匿名类)

C#中的匿名方法是一种没有名称只有主体的方法,它提供了一种传递代码块作为委托参数的技术。以下是关于C#匿名方法的一些重要特点和用法:特点省略参数列表:使用匿名方法可省略参数列表,这意味着匿名方法...

C# Windows窗体(.Net Framework)知识总结

Windows窗体可大致分为Form窗体和MDI窗体,Form窗体没什么好细说的,知识点总结都在思维导图里面了,下文将围绕MDI窗体来讲述。MDI(MultipleDocumentInterfac...