爬蟲精髓:使用.*?進行匹配獲取內容
python小技巧: alt加回車鍵快速導包
文章目錄
- 一、json相關方法及用法
- 1. json的概念
- 2. json的操作
- 1. json.dumps()和json.loads()是將python中的list或dict轉換成json語句(可以這麼理解爲操作數據)
- (1) json.dumps()函數是將一個Python數據類型列表進行json格式的編碼(可以這麼理解,json.dumps()函數是將字典轉化爲字符串)
- (2) json.loads()函數是將json格式數據轉換爲字典(可以這麼理解,json.loads()函數是將字符串轉化爲字典)
- 2. json.dump()和json.load()主要用來讀寫json文件函數(可以理解爲操作文件)
- (2)當我們要讀取json文件的時候使用到json.load將json文件轉換成python的list或dict
- 二、使用正則抓取數據案例
一、json相關方法及用法
1. json的概念
-
定義:JSON 的 全稱是 JavaScript Object Notation,即 JavaScript 對象符號,它是一種輕量級、跨平臺、跨語言的數據交換格式。
-
設計意圖:把所有事情都用設計的字符串來表示,這樣既方便在互聯網上傳遞信息,也方便人進行閱讀。
-
發展:最早的時候,JSON 是 JavaScript 語言的數據交換格式,後來慢慢發展成一種語言無關的數據交換格式,這一點非常類似於 XML。
-
使用範圍:JSON 主要在類似於C 的編程語言中廣泛使用,這些語言包括 C、C++、C#、Java、JavaScript、Perl、Python 等。JSON 提供了多種語言之間完成數據交換的能力,因此,JSON 也是一種非常理想的數據交換格式。
-
JSON 主要有如下兩種數據結構(語法):
(1)由 key-value 對組成的數據結構(對象)
這種數據結構在不同的語言中有不同的實現。例如,在 JavaScript 中是一個對象;在 Python 中是一種 dict 對象;在 C 語言中是一個 struct;在其他語言中,則可能是 record、dictionary、hash table 等。
(2)有序集合(數組)
這種數據結構在 Python 中對應於列表;在其他語言中,可能對應於 list、vector、數組和序列等。
總結:上面兩種數據結構在不同的語言中都有對應的實現,因此這種簡便的數據表示方式完全可以實現跨語言。所以,JSON 可以作爲程序設計語言中通用的數據交換格式。
可以簡潔爲以下幾點:
- json是一種通用的數據類型
- 一般情況下接口返回的數據類型都是json
- 長得像字典,形式也是key-value
- 其實json是字符串
- 字符串不能用key、value來取值,所以要先轉換爲字典纔可以
2. json的操作
1. json.dumps()和json.loads()是將python中的list或dict轉換成json語句(可以這麼理解爲操作數據)
(1) json.dumps()函數是將一個Python數據類型列表進行json格式的編碼(可以這麼理解,json.dumps()函數是將字典轉化爲字符串)
import json
# json.dumps()函數的使用,將字典轉化爲字符串
dict1 = {"age": "12"}
json_info = json.dumps(dict1)
print("dict1的類型:"+str(type(dict1)))
print("通過json.dumps()函數處理:")
print("json_info的類型:"+str(type(json_info)))
運行截圖:
(2) json.loads()函數是將json格式數據轉換爲字典(可以這麼理解,json.loads()函數是將字符串轉化爲字典)
import json
# json.loads函數的使用,將字符串轉化爲字典
json_info = '{"age": "12"}'
dict1 = json.loads(json_info)
print("json_info的類型:"+str(type(json_info)))
print("通過json.dumps()函數處理:")
print("dict1的類型:"+str(type(dict1)))
運行截圖:
2. json.dump()和json.load()主要用來讀寫json文件函數(可以理解爲操作文件)
(1)一般將獲取到的內容放在json文件中
這就用到了json.dump將python的list或dict數據放入json文件中
格式:
json.dump(python的dict或list,fp'json文件')
例子:
with open('guba.json','w',encoding='utf-8') as fp:
json.dump(info,fp)
運行截圖:
(2)當我們要讀取json文件的時候使用到json.load將json文件轉換成python的list或dict
格式:
json.load(fp'json文件')
例子:
with open('guba.json','r') as fp:
guba_list = json.load(fp)
for one in guba_list:
print(one)
運行截圖:
總結:不管是dump還是load,帶s的都是和字符串(數據)相關的,不帶s的都是和文件相關的。
二、使用正則抓取數據案例
- 總結:用正則篩選數據,有個原則:不斷縮小篩選訪問
1. 案例:貓眼電影
- 需求:
- 電影名稱
- 主演
- 上映時間
- 評分
- 代碼:
import requests,re,json
class Cat_moive():
def __init__(self,url):
self.url = url
self.movie_list=[]
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
## 調用自己的parse方法
self.parse()
def parse(self):
## 爬取頁面的代碼
# 1. 發送請求,獲取響應
# 分頁
for i in range(10):
url = self.url+'?offset={}'.format(i*10)
response = requests.get(url,headers = self.headers)
# print(response.text)
"""
1. 電影名稱
2. 主演
3. 上映時間
4. 評分
"""
## 用正則篩選數據,有個原則:不斷縮小篩選訪問
dl_pattern = re.compile(r'<dl class="board-wrapper">(.*?)</dl>',re.S)
dl_content = dl_pattern.search(response.text).group()
# print(dl_content)
dd_pattern = re.compile(r'<dd>(.*?)</dd>', re.S)
dd_list = dd_pattern.findall(dl_content)
# print(dd_list)
for dd in dd_list:
item = {}
## 拿電影名稱
movie_pattern = re.compile(r'title="(.*?)" class=', re.S)
movie_name = movie_pattern.search(dd).group(1)
# print(movie_name)
## 拿演員
actor_pattern = re.compile(r'<p class="star">(.*?)</p>', re.S)
actor = actor_pattern.search(dd).group(1).strip()
# print(actor)
## 上映時間
play_time_pattern = re.compile(r'<p class="releasetime">(.*?):(.*?)</p>')
play_time = play_time_pattern.search(dd).group(2).strip()
# print(play_time)
## 評分
grade_pattern = re.compile(r'<i class="integer">(.*?)</i><i class="fraction">(.*?)</i>',re.S)
grade1 = grade_pattern.search(dd).group(1)
grade2 = grade_pattern.search(dd).group(2)
grade = grade1+grade2
# print(grade)
item["movie_name"]=movie_name
item["actor"]=actor
item["play_time"]=play_time
item["grade"]=grade
self.movie_list.append(item)
# print(self.movie_list)
## 將電影信息保存到json文件中
with open ('movie.json','w',encoding='utf-8') as fp:
json.dump(self.movie_list,fp)
if __name__ == '__main__':
base_url = 'https://maoyan.com/board/4'
Cat_moive(base_url)
with open('movie.json', 'r') as fp:
movie_list = json.load(fp)
# print(movie_list)
for item in movie_list:
print(item)
- 運行結果:
2. 案例:股吧
- 需求:
- 閱讀數
- 評論數
- 標題
- 作者
- 更新時間
- 詳情頁的url
- 代碼:
import json
import requests,re
# 確定url
base_url = 'http://guba.eastmoney.com/default,99_%s.html'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
for i in range(1,13):
response = requests.get(base_url %i,headers=headers)
# print(response.text)
"""
閱讀數
評論數
標題
作者
更新時間
詳情頁的url
"""
## 獲取ul
ul_pattern = re.compile(r'<ul class="newlist" tracker-eventcode="gb_xgbsy_ lbqy_rmlbdj">(.*?)</ul>',re.S)
ul_content = ul_pattern.search(response.text)
if ul_content:
ul_content = ul_content.group()
## 獲取所有li
li_pattern = re.compile(r'<li>(.*?)</li>', re.S)
li_list = li_pattern.findall(ul_content)
# print(ul_content)
info = []
for li in li_list:
item = {}
reader_pattern = re.compile(r'<cite>(.*?)</cite>',re.S)
info_list = reader_pattern.findall(li)
# print(info_list)
read_num = ''
comment_num = ''
## 獲取閱讀數和評論數
if info_list:
read_num = info_list[0].strip()
comment_num = info_list[1].strip()
# print(read_num,comment_num)
## 獲取標題
title_pattern = re.compile(r'title="(.*?)" class="note"',re.S)
title = title_pattern.search(li).group(1)
# print(title)
## 獲取作者
author_pattern = re.compile(r'target="_blank"><font>(.*?)</font>',re.S)
author = author_pattern.search(li).group(1)
# print(author)
## 獲取時間
time_pattern = re.compile(r'<cite class="last">(.*?)</cite>',re.S)
time = time_pattern.search(li).group(1)
# print(time)
## 獲取詳情頁
datail_pattern = re.compile(r'</em> <a href="(.*?)" title=',re.S)
datail_url = datail_pattern.search(li)
if datail_url:
datail_url ='http://guba.eastmoney.com' + datail_url.group(1)
else:
datail_url=''
# print(datail_url)
##加入字典中
item['title'] = title
item['read_num'] = read_num
item['comment_num'] = comment_num
item['author'] = author
item['time'] = time
item['datail_url'] = datail_url
info.append(item)
# 保存成json文件
with open('guba.json','w',encoding='utf-8') as fp:
json.dump(info,fp)
## 查看json文件中的列表
with open('guba.json','r') as fp:
guba_list = json.load(fp)
for one in guba_list:
print(one)
- 運行結果:
3. 將匹配正則函數封裝成面向對象
(1)案例:股吧
- 要求:
“”"
閱讀數
評論數
標題
作者
更新時間
詳情頁的url
“”" - 代碼:
import json
import requests,re
class Guba:
def __init__(self,url):
self.url = url
## 存放所有信息
self.info = []
self.parse()
def get_content(self,url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.text
return None
def parse(self):
for i in range(1, 13):
content = self.get_content(self.url %i)
## 獲取ul
ul_pattern = re.compile(r'<ul class="newlist" tracker-eventcode="gb_xgbsy_ lbqy_rmlbdj">(.*?)</ul>', re.S)
ul_content = ul_pattern.search(content)
if ul_content:
ul_content = ul_content.group()
## 獲取所有li
li_pattern = re.compile(r'<li>(.*?)</li>', re.S)
li_list = li_pattern.findall(ul_content)
# print(ul_content)
for li in li_list:
item = {}
reader_pattern = re.compile(r'<cite>(.*?)</cite>', re.S)
info_list = reader_pattern.findall(li)
# print(info_list)
read_num = ''
comment_num = ''
## 獲取閱讀數和評論數
if info_list:
read_num = info_list[0].strip()
comment_num = info_list[1].strip()
# print(read_num,comment_num)
## 獲取標題
title_pattern = re.compile(r'title="(.*?)" class="note"', re.S)
title = title_pattern.search(li).group(1)
# print(title)
## 獲取作者
author_pattern = re.compile(r'target="_blank"><font>(.*?)</font>', re.S)
author = author_pattern.search(li).group(1)
# print(author)
## 獲取時間
time_pattern = re.compile(r'<cite class="last">(.*?)</cite>', re.S)
time = time_pattern.search(li).group(1)
# print(time)
## 獲取詳情頁
datail_pattern = re.compile(r'</em> <a href="(.*?)" title=', re.S)
datail_url = datail_pattern.search(li)
if datail_url:
datail_url = 'http://guba.eastmoney.com' + datail_url.group(1)
else:
datail_url = ''
# print(datail_url)
##加入字典中
item['title'] = title
item['read_num'] = read_num
item['comment_num'] = comment_num
item['author'] = author
item['time'] = time
item['datail_url'] = datail_url
self.info.append(item)
if __name__ == '__main__':
# 確定url
base_url = 'http://guba.eastmoney.com/default,99_%s.html'
g = Guba(base_url)
# 保存成json文件
with open('guba1.json','w',encoding='utf-8') as fp:
json.dump(g.info,fp)
## 查看json文件中的列表
with open('guba1.json','r') as fp:
guba_list = json.load(fp)
for one in guba_list:
print(one)
- 運行結果:
(2)案例:藥網
- 需求:
1. 總價
2. 描述
3. 評論數量
4. 詳情頁鏈接 - 代碼:
import json
import requests,re
class Yaowang:
def __init__(self,url):
self.url = url
self.info = []
self.parse()
def get_content(self,url):
headers={'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
response = requests.get(url,headers=headers)
if response.status_code == 200:
return response.text
return None
def parse(self):
for i in range(1,51):
content = self.get_content(self.url+'/categories/953710-j%s.html' %i)
"""
總價,
描述,
評論數量,
詳情頁鏈接
"""
ul_pattern = re.compile(r'<ul id="itemSearchList" class="itemSearchList">(.*?)</ul>',re.S)
ul_content = ul_pattern.search(content).group(1)
li_list_pattern = re.compile(r'<li id="producteg_(.*?)</li>',re.S)
li_list = li_list_pattern.findall(ul_content)
if li_list:
for li in li_list:
item = {}
total_pattern = re.compile(r'<span>(.*?)</span>',re.S)
total = total_pattern.search(li).group(1).strip()
# print(total)
description_pattern = re.compile(r' <span class=" list_lable_self"></span>(.*?)</a>',re.S)
description = description_pattern.search(li)
if description:
description = description.group(1).strip()
else:
description = ''
# print(description)
comment_pattern = re.compile(r'評論 <em>(.*?)</em>條',re.S)
comment = comment_pattern.search(li)
# print(comment)
if comment:
comment = comment.group(1)
else:
comment = ''
detail_pattern = re.compile(r' " href="//www.111.com.cn(.*?)"',re.S)
detail_url = detail_pattern.search(li).group(1)
detail_url = self.url + detail_url
# print(detail_url)
item['total']=total
item['description']=description
item['comment']=comment
item['detail_url']=detail_url
self.info.append(item)
if __name__ == '__main__':
base_url = 'https://www.111.com.cn'
yw = Yaowang(base_url)
with open('yw.json','w',encoding='utf-8') as fp:
json.dump(yw.info,fp)
with open('yw.json','r') as fp:
info_list = json.load(fp)
for one in info_list:
print(one)
- 運行結果: