爬虫之 JS(返回非 json 数据)的爬取

爬虫之 JS(返回非 json 数据)的爬取

写在前面的话: 查资料,看到常用浏览器的 user-agent 参考对照表,因为之前爬取百度文库的时候用到手机的请求头,所以就想把这些所有请求头爬下来,结果遇到一系列问题,进而解决,从而记录下来。

一. 爬取内容

常用浏览器(PC,移动)的 user-agent

简介:该对照表整理了时下流行的浏览器User-Agent大全,User Agent也简称UA。它是一个特殊字符串头,是一种向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。并悬浮提示来访者的user-agent信息。

下面是要爬取的内容

查找元素,发现可以找到!数据这么规整会以为很容易啊!但是用xpath去提取总是空白的,去查看网页源代码,可达鸭眉头一皱,发现事情没有这么简单。

放入最基本的代码

import requests
from lxml import etree

headers = {
  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"
}

url = 'http://tools.jb51.net/table/useragent'

html = requests.get(url, headers=headers)
html.encoding = 'utf-8'
text = html.text
二. 网页原理

看图片

这是用 js 代码加进去的,并不能通过网页元素查到,所以xpath直接提取是不行喽,而且返回不到 json 数据,那就得想想办法了。

最简单的正则,用来用去,掀起小板凳,砸掉电脑,pass!
用bs大法……与xpath一样无从下手,pass!

经查资料,发现有个解析 js 的库 —— js2xml
开始尝试,具体的使用方法还请耐心往下看

import js2xml
  • pip install js2xml 即可安装

当然,先要获取js代码段,也就是 script 标签内的内容,为什么是取第3个,自然是根据网页来定了,我要的内容在第3个元素里,自然取它了!

lx = etree.HTML(text)
scripts = lx.xpath("//script/text()")[3]
三. 解析JS代码

重点就在于 js2xml.parse(scripts) 方法

parsed = js2xml.parse(scripts)
xml_file = js2xml.pretty_print(parsed)
print(xml_file)

重点: 这个方法得到了什么内容,让我们查看一下,发现就是规整的xml文件,但上述的 xml_file 是 str 类型,我们完全可以用 xpath 或 bs 去获取我们想要的了!是不是很简单?

四. 爬取内容

在这里用了 xpath

names1 = script.xpath("//var[@name='pcj']//text()")
names2 = script.xpath("//var[@name='mbj']//text()")

infos1, infos2 = [], []
for name in names1:
    if name:
        infos1.append(name)
for name in names2:
    if name:
        infos2.append(name)
dic1, dic2 = {}, {}
for i in range(1, len(infos1)):
    if i % 2 != 0:
        s = infos1[i].split('User-Agent,')[1]
        dic1[infos1[i-1]] = s
for i in range(1, len(infos2)):
    if i % 2 != 0:
        s = infos2[i].split('User-Agent,')[1]
        dic2[infos2[i-1]] = s
五. 完整代码

中间有部分数据处理的过程,比如去掉字符串中的 “User-Agent”,通过分析数据格式来存储,个人习惯用pandas做存储,也可以直接分析嘛,毕竟数据量小,不需要用安全队列去搞

# -*- encoding: utf-8 -*-
# user_agent.py
# @Time  :  2019/05/07 17:13:11
# @Author:  小木
# @email :  hunt_hak@outlook.com

# here put the import lib
import pandas as pd
import requests
import re
import pandas as pd
import js2xml
from lxml import etree

def get_html(url):
    headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"
    }


    html = requests.get(url, headers=headers)
    html.encoding = 'utf-8'
    text = html.text
    return text

def parse_xml(text):
    lx = etree.HTML(text)
    scripts = lx.xpath("//script/text()")[3]

    parsed = js2xml.parse(scripts)
    xml_file = js2xml.pretty_print(parsed)

    html = etree.HTML(xml_file)
    return html

def get_dic(l):

    dic = {}
    infos = []
    names = [i.strip() for i in l]
    for i in names:
        if i:
            infos.append(i)
    
    for i in range(1, len(infos)):
        if i % 2 != 0:
            s = infos[i].split('User-Agent,')[1]
            dic[infos[i-1]] = s

    return dic

def save_to_csv(dic, filename):
    dic_list = [dic]
    datas = pd.DataFrame(dic_list)
   	datas.to_csv(filename+'.csv', index=None)

if __name__ == "__main__":
    
    url = 'http://tools.jb51.net/table/useragent'
    text = get_html(url)
    script = parse_xml(text)

    names1 = script.xpath("//var[@name='pcj']//text()")
    names2 = script.xpath("//var[@name='mbj']//text()")
    dic1 = get_dic(names1)
    dic2 = get_dic(names2)
    # print(dic1, dic2)
    save_to_csv(dic1, "PC")
    save_to_csv(dic2, "MOBILE")

欢迎批评指正~

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值