第三天:

数据的分类

  1. 基础知识
  2. Json的知识点复习
  3. 正则表达式的复习

 

 

数据提取

什么是数据的提取?

      简单来说就是从响应中获取我们想要的数据的过程

 

数据分类

  1. 非结构化数据:html等   处理方法:正则表达,xpath
  2. 结构化数据: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页

https://movie.douban.com/tv/

 

 

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()




----------------------------------------------------------------------------------------------------