第三天:
数据的分类
- 基础知识
- Json的知识点复习
- 正则表达式的复习
数据提取
什么是数据的提取?
简单来说就是从响应中获取我们想要的数据的过程
数据分类
- 非结构化数据:html等 处理方法:正则表达,xpath
- 结构化数据:json, xml等 处理方法:转化为python数据类型
数据提取之json
由于把json数据转化为python内建数据类型很简单,所以爬虫中,如果我们能够找到返回json数据的URL,就会尽量使用这种URL
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
数据提取值json
Json字符串àjson.loads()àpython数据类型
python数据类型àjson.dumps()àJson字符串
包含Json的类文件对象àjson.load()àpython数据类型
python数据类型àjson.dump()à包含Json的类文件对象
具有read()或者write()方法的对象就是类文件对象
f = open(“a.txt”,”r”) f就是类文件对象
爬取豆瓣网举个例子:
import requests
import json
from pprint import pprint
url = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&page_limit=50&page_start=0"
response = requests.get(url)
print(response.content.decode())
# json.loads()把json字符串转化为python类型
ret = json.loads(response.content.decode())
# 运用pprint会好看一点
# pprint(ret)
# print(type(ret))
# json.dumps能够把python类型转化为json字符串
with open('douban.json', "w") as f:
# ensure_ascii = False转换成中文
# indent=2格式更好看
f.write(json.dumps(ret, ensure_ascii=False, indent=2))
#使用json.load提取文件对象中的数据
# with open("douban.json", "r", encoding="gbk")
as f:
# ret1 = json.load(f)
# print(ret1)
Json使用注意点:
Json中的字符串都是双引号引起来的,如果不是双引号就不是json。
Json在数据交换起到了一个载体的作用,承载着相互传递的数据。
小练习:爬取豆瓣热门电视剧排行榜10页
import requests
import json
class DoubanSpider:
def __init__(self):
self.url_temp
= "https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start={}"
self.headers
= {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"}
# 2.发送请求,获取响应
def parse_url(self, url):
response = requests.get(url, headers=self.headers)
return response.content.decode()
# 3.提取数据
def get_content_list(self,
json_str):
# json字符串转化成python数据类型
dict_ret = json.loads(json_str)
content_list = dict_ret["subjects"]
return content_list
# 4.保存
def save_content_list(self,
content_list):
# a是追加
with open("doubantv.txt","a", encoding="utf-8") as f:
for content
in content_list:
f.write(json.dumps(content, ensure_ascii=False))
# 换行
f.write("\n")
def run(self):#实现主要逻辑
num = 0
for i in range(10):
# 1.start_url
url = self.url_temp.format(num)
# 2.发送请求,获取响应
json_str = self.parse_url(url)
# 3.提取数据
content_list = self.get_content_list(json_str)
# 4.保存
self.save_content_list(content_list)
# 5.构造下一个url地址
num += 20
# 6.循环(2,3,4,5)
if __name__ == "__main__":
douban_spider = DoubanSpider()
douban_spider.run()
正则表达式的复习:
正则表达式的定义:
就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个"规则字符串",这个"规则字符串"用来表达对字符串的一种过滤逻辑。
常用正则表达式的方法:
re.compile(编译)
re.findall(找所有)用的最多
re.sub(替换)
import re
a = re.findall(".", "\n")
print(a)
b = re.findall(".", "\n", re.DOTALL)
print(b)
c = re.findall(".", "\n", re.S)
print(c)
# 不能匹配,只能匹配中括号里面的一个
d = re.findall("a[bcd]e", "abce")
print(d)
# 加一个"+"就行了
e = re.findall("a[bcd]+e", "abce")
print(e)
# 随便打开网页源代码复制几行
f = '''<div id="header-wrapper"
class="clearfix">
<div id="usrbar" alog-group="userbar" alog-alias="hunter-userbar-start"></div>
<ul id="header-link-wrapper" class="clearfix">'''
# 贪婪(尽可能多的匹配)
print(re.findall("<.*>", f, re.S)) # 因为里面有我们看不到的换行符,所以要用re.S
# 非贪婪
print(re.findall("<.*?>", f, re.S))
# 替换 sub
g = "guanzhou1yueqian2"
#把数字替换成下划线
print(re.sub('\d','_',g))
#把数字替换成空字符串
print(re.sub('\d','',g))
# 编译 compile
h = re.compile("\d")
print(h.findall(g))
小练习:通过正则表达式匹配糗事百科的作者
https://www.qiushibaike.com/text/
import requests
import re
import json
class Qiushi:
def __init__(self):
self.start_url = "https://www.qiushibaike.com/text/page/{}/"
self.headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"}
# 2.发送请求,获取响应
def parse_url(self, url):
response = requests.get(url, headers=self.headers)
return response.content.decode("utf-8")
# 3.提取数据
def get_first_page_content_list(self, html_str):
content_list = re.findall(r'<h2>(.*?)</h2>', html_str, re.S)
return content_list
#4.保存
def save_content_list(self, content_list):
with open("qishi.txt", "a", encoding="utf-8") as f:
for content in content_list:
f.write(json.dumps(content, ensure_ascii=False, indent=4))
def run(self):# 实现主逻辑
#1.start_url
for i in range(3):
url = self.start_url.format(i+1)
#2.发送请求,获取响应
html_str = self.parse_url(url)
#3.提取数据
content_list = self.get_first_page_content_list(html_str)
#4.保存
self.save_content_list(content_list)
if __name__ == "__main__":
qiushi = Qiushi()
qiushi.run()
----------------------------------------------------------------------------------------------------