网络爬虫-4:jsonpath+实战

发布于:2025-03-26 ⋅ 阅读:(32) ⋅ 点赞:(0)

1.jsonpath
2.通过jsonpath实战

一.Jasonpath核心符号

1)$:

  1. 含义:表示 JSON 文档的根节点。

  2. 用法:所有 JSONPath 表达式都以 $ 开头,表示从根节点开始查询。

{
  "store": {
    "book": [
      {"title": "Book 1", "price": 10},
      {"title": "Book 2", "price": 20}
    ]
  }
}

$ 表示整个 JSON 文档。

2) . :

  • 含义:用于访问对象的属性。

  • 用法:通过点号 . 可以访问对象的属性。

$.store 表示获取 store 对象。

$.store.book 表示获取 store 对象中的 book 数组。

from jsonpath import jsonpath
data={
  "store": {
    "book": [
      {"title": "Book 1", "price": 10},
      {"title": "Book 2", "price": 20}
    ]
  }
}
store=jsonpath(data,"$.store")
book = jsonpath(data,"$.store.book")
print(store)
print(book)
[{'book': [{'title': 'Book 1', 'price': 10}, {'title': 'Book 2', 'price': 20}]}]
[[{'title': 'Book 1', 'price': 10}, {'title': 'Book 2', 'price': 20}]]

3) [ ]:

  • 含义:用于访问数组元素或对象的属性(支持属性名或索引)。

  • 用法

    • 访问数组元素:[index]

    • 访问对象属性:['property']

$.store.book[0] 表示获取 book 数组的第一个元素。

$['store']['book'][0] 也可以用于访问属性。

from jsonpath import jsonpath
data={
  "store": {
    "book": [
      {"title": "Book 1", "price": 10},
      {"title": "Book 2", "price": 20}
    ]
  }
}
a = jsonpath(data,"$.store[book]")
b = jsonpath(data,"$[store][book][0]")
print(a)
print(b)
[[{'title': 'Book 1', 'price': 10}, {'title': 'Book 2', 'price': 20}]]
[{'title': 'Book 1', 'price': 10}]

4) .. :

  • 含义:递归下降,表示从当前节点开始递归搜索所有子节点。

  • 用法:用于查找 JSON 文档中所有符合条件的节点。

$..title 表示在整个 JSON 文档中查找所有 title 属性。

$..book 表示查找所有 book 节点。

from jsonpath import jsonpath
data={
  "store": {
    "book": [
      {"title": "Book 1", "price": 10},
      {"title": "Book 2", "price": 20}
    ]
  }
}
a = jsonpath(data,"$..title")
b = jsonpath(data,"$..book")
print(a)
print(b)
['Book 1', 'Book 2']
[[{'title': 'Book 1', 'price': 10}, {'title': 'Book 2', 'price': 20}]]

5)@:

  • 含义:在过滤器表达式中表示当前节点。

  • 用法:用于在 ?() 中引用当前节点。

$.store.book[?(@.price < 10)] 中的 @ 表示当前 book 元素。

6)?():

  • 含义:过滤器表达式,用于根据条件筛选数据。

  • 用法:在 ?() 中编写条件表达式,筛选符合条件的节点。

$.store.book[?(@.price < 10)] 表示获取 book 数组中价格小于 10 的所有元素。

$.store.book[?(@.category == 'fiction')] 表示获取 category 为 fiction 的书籍。

二.实战

当网页返回的源代码为json格式时,使用JSONPATH进行网页爬取

1.通过判断,腾讯网 为异步加载,所以要查看Fetch/XHR

2.在通过jsonpath获取想要的信息部分

import requests
from jsonpath import jsonpath
import random
def get_data(url,headers,payload):
    response = requests.post(url, headers=headers,json=payload)
    if response.status_code == 200:
        html_data = response.json()
        return html_data
    else:
        print("请求代码:",response.status_code)

def parse_json(html_data):
    titles = jsonpath(html_data,'$.data..title')
    times = jsonpath(html_data,'$..publish_time')
    hrefs = jsonpath(html_data,'$..link_info[url]')
    for title,time,href in zip(titles,times,hrefs):
        print("新闻标题:",title)
        print("发布时间:",time)
        print("新闻链接:",href)


if __name__ == '__main__':
    url="https://i.news.qq.com/web_feed/getHotModuleList"
    USER_AGENTS = [
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
        "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
        "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
        "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)"
    ]
    headers = {
        "user-agent": random.choice(USER_AGENTS),
        "cookie": "你的cookies"
    }
    payload={
    "你的浏览器requests payload"
    }
    html_data = get_data(url,headers,payload)
    parse_json(html_data)