python(数据分析与可视化)四

python(数据分析与可视化)四

动态网站的爬取

今天我们来讲解一下有关js动态加载后的数据爬取

1.京东评论初步尝试

import requests
from lxml import etree

#单个商品详情页url
url = 'https://item.jd.com/100009077475.html'
headers = {
    #没有user-agent 返回简短的html代码,js重定向到首页
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
}
#请求图集页
resp = requests.get(url,headers=headers)
if resp.status_code == 200:
    html = resp.text
    print(html)   #得到一些html源代码,为具体表现
   
    dom = etree.HTML(html)
    pattern = '//div[@class ="comment-item"]//p[@ class ="comment-con"]/text()'
    comments = dom.xpath(pattern)
    print(len(comments),comments)
   

经过类似于上一博客讲解的静态网页数据的爬取,我们会发现 xpath可以在开发者工具elements中匹配11条评论,但是代码中匹配到的确实空列表,这就是涉及到了跨域,下面我们一步一步来进行分析。

2.动态网站和静态网站分析

1.静态网站
几乎所有的后端语言的web框架,java ssh、php、python flask django.服务端web程序接收到请求后,从数据库取数据,把数据拼凑到事先准备的html模板骨架中,形成一个完整的网页html,最终响应,浏览器解析,用户看到效果。这种技术非常流行,广义上来说是动态网站,狭义上来说响应前html已经确定好了。
缺点:如果页面已经变更,需要刷新页面才能看到,需要手动频繁刷新页面,不刷新就可能错失信息,刷新又太累。

2.js动态网站
第一次请求从后台收到html源代码,html源代码只有网页菜单导航等公共部分和js,浏览器拿到第一次响应,解析js,js中发起后续异步后台请求,从后台拿到纯数据,通过js把数据渲染某一处div里面,最终用户看到完整网页。
优点:传输更快,首屏加载更快,局部更新,体验更好
场景:评论、微博 朋友圈提示、注册表单再提交前提示用户已注册

两者间的分别
第一次url document请求得到的源代码,同网页最终(开发者工具elements)比对:
1.如果一致,静态网站
2.整个网页刷新 -> 静态 局部刷新->动态
3.xpath是否能取到目标数据,如果娶不到,则数据在后续的js请求里

3.评论请求寻找分析

  • 找js xhr请求评论数据,不关心对方js怎么写和渲染到网页,只要找到http请求,然后用python模拟

寻找技巧
1.开发者工具network,过滤xhr、js请求
2.找post类型的请求
3.找比较像的名字 comment api get_info get+list
4.响应的是纯数据,而不是html信息
5.尝试在网页中触发异步js数据请求,在开发者工具中看有没有新增请求
6.network工具获取焦点,ctrl+f 打开隐藏的搜索框,在所有请求、请求头,响应全文搜索关键字

4.json格式

为什么用json,xml,而不用list ,dict等,这是因为不同计算机互相交流数据,每种计算机用的编程语言不同,java,php,python,C,C++,Go
类似的结构,因为解释器底层实现不一样,表现同样数据的二进制不一样,每一台计算机上的编程语言和服务不一样,需求‘中间格式’,所以,有统一格式,XML和Json,【字符串】

  • json可以做数据传输文件

XML 过去很流行,但很麻烦,现在用的少

Json格式 字符串
json格式语法: {}内键值对属性和值,[]数组一组,基本类型 整型,字符串。字符串用【双引号】
json里只能使用双引号
下面是一个简单的举例:

import json

xiaoming_json_str = """
      {
          "name": "小明",
          "age": 54,
          "parent": [
              {
                  "name": "小明爸爸"
              },
              {
                  "name": "小明妈妈"
              }
          ]
      }
"""
#打印在控制台的结果看不出变量是字符串还是字典,应该用type()函数判读
print(type(xiaoming_json_str),xiaoming_json_str)
#json字符串 ->  python内置数据结构
xiaoming_dict = json.loads(xiaoming_json_str)
#json.losd(本地文件.json)
print(type(xiaoming_dict),xiaoming_dict)
print(xiaoming_dict['name'])
for parent in xiaoming_dict['parent']:
    print(parent['name'])


#python内置数据结构 -> json 字符串
students = [
    {'name': "小红", 'age': 14, 'gender': '男'},
    {'name': "小明", "age": 15, "gender": "男"},
    {'name': "小明", "age": 11, "gender": "女"}

]
students_json_str = json.dumps(students)
print(type(students_json_str), students_json_str)

5.请求京东评论接口

接下来就是一个比较完整的京东评论接口的爬取实例了:

import json
import requests

base_url = 'https://club.jd.com/comment/productPageComments.action'

#本次请求头只用伪造users-agent即可,但前段时间测试需要cookie字段
headers = {
    # 'Cookie': '__jdv=76161171|direct|-|none|-|1610928737206; __jdu=1610928737155940443424;',
    # 'Referer': 'https://item.jd.com/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'
}

#tips:从开发者工具network请求头下面的query params复制下来再调整,使用编辑器列编辑模式 alt+shif+鼠标拖动
params = {
    #'callback': 'fetchJSON_comment98',  #特殊的 jsonp->json
    'productId': 100009077475, #商品id
    'score': 0,
    'sortType': 5,
    'page': 1,                 #第几页
    'pageSize': 10,
    'isShadowSku': 0,
    'rid': 0,
    'fold': 1
}

resp = requests.get(base_url,headers=headers,params=params)
status_code = resp.status_code
comments_json = resp.text
print(comments_json)

comments_obj = json.loads(comments_json)
print(comments_json)
comments = comments_obj['comments']
for c in comments:
    #print(c)
    cid = c['id']
    content = c['content']
    creation_time = c['creationTime']
    images = c['images']
    product_color = c['productColor']
    print('-'*100)
    print(cid,content)

其中需要注意的是,京东评论接口返回得到的是jsonp 格式,涉及跨域问题,需要先将jsonp转为json
方法一:python字符串方法删除固定长度无用字符串
方法二:(推荐)上网找从jsonp过滤json正则
方法三:本例中发现修改参数可以直接访问json

今天的分享就到这里,如果还想了解更多,可以看我主页!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值