python爬虫 | 异步加载网页的链接问题 | 小白速成篇


今天刚学,都是个人理解,不准确或者错误的地方,跪求大佬轻喷,┭┮﹏┭┮

好像写的很乱,大概就是,跟着我说的做一遍,应该会有一个基本的了解~~


前言:
    python课最后的实验报告是要爬取一个异步加载网页的数据,然后,很多人就懵了,点下一页,URL不变。对从豆瓣 top250 开始学爬虫的小白及其不友好,骂骂咧咧的打开B站,这代码真白,呸,这代码真妙
    我看了大佬的视频,大概要几个小时可以全部看完,不喜欢看文字的同学:
先点这里~~~
再点这里~~~
看完了吧,可以退场了,😀

然后开始讲文字部分。

问题分析:

  1. 准备工作,这里是分析源码,找到页面数据部分的访问链接(个人理解,用词不一定准确)
    ps:这个就是问题所在,异步加载网页的数据访问链接不容易找到
  2. 获取数据,这里是通过找到的规律,获取不同的数据(指数据源码)
    ps:常规操作,得到 json 即可
  3. 解析数据,这里是指对 json 内容的处理
    ps:python 不愧是被封装到牙齿的语言阿,直接用 json 的包处理即可
  4. 保存数据,存到数据库里边吧
    ps:送佛送到西

我们直接找个实例来讲,
请出我们的小白鼠:http://quote.eastmoney.com/center/gridlist.html#hs_a_board
对,我报告就是写的这个网页,别抄
在这里插入图片描述
在这里插入图片描述
发现了吧,点翻页,链接不变

知识点:

ajax,页面异步交互
举个例子:在这里插入图片描述
如果是在同步刷新的情况下,当请求正常返回时,整个页面都会进行刷新
但是在页面异步交互的情况下,只有 div1 的内容会进行一次刷新

我们在对异步交互的网页爬取时,要怎么做呢?
很简单,模仿 div1 发出请求,得到返回数据

下边就来说说,div1 如何发出请求,轻轻按下F12,进入开发者模式
ps:当然要去小白鼠页面按了,在这里按屁都看不出来
在这里插入图片描述
点这个网络,好像有的浏览器是英文,翻译翻译就好了。
我们可以注意到 ① 的内容,这个就是网页向服务器发送的请求信息,忘记说了,点一下左上角的红点点,不然会一直记录请求信息
随便找一个请求信息,点一下
在这里插入图片描述
标头记录的信息就是使用者的各种信息,注意我画圈的这个地方就好了,User-Agent:… ,这条信息会告诉服务器你是什么样的浏览器,我们在模拟网页向服务器发送请求时,要设置这条,不然就会 418,也就意味着,你被人家发现你在爬虫了~~~
ps:敬告大家,少看小破站,不然所有的信息都被人家搜集走了在这里插入图片描述
我们继续,敲黑板,重点来了:
在这里插入图片描述
按照,1,2,3,4,5 的顺序点,你会得到图六的效果,再然后
在这里插入图片描述
按照 1,2,3,然后 ctlr + v
就会得到这个:
http://46.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112403404865712147702_1623771689089&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1623771689370

嗯,这个就是向服务器发送请求的东东,把这个复制到另一个新的网页里,然后就是这样:
在这里插入图片描述
这堆代码,就是服务器返回的信息,这是一种 json语言,有兴趣的就百度一下吧~

这里我们请出一个工具:https://www.bejson.com/,可以放心打开
在这里插入图片描述
把,刚刚那堆东西复制过来,然后点格式化校验,然后就是
在这里插入图片描述
报错了,删掉画线的内容就行了~
在这里插入图片描述
在这里插入图片描述
然后再点校验,他会告诉你没毛病~~
在这里插入图片描述
我相信你可以发现,每一对大括号对应的就是一组数据

到这里,我们就结束了前导内容的准备

获取数据

上边的内容告诉我们,我们只需要研究
在这里插入图片描述
箭头指向这个东东,多复制几个链接下来
在这里插入图片描述
在这里插入图片描述
这个链接很长,共有两处不同,可以明显发现,第一处最有可能是控制页码的参数,第二处是干嘛的我也不知道没试出来

下边,我们就开始写代码,把刚刚的 json 内容给爬下来

import re
import urllib
import json
import time
import pymysql

def askURL(url):
	# 这里就是一个伪装,复制上边标头处的信息即可,可以试试把这个设为空,🐕
	#注意 User-Agent 一定不能打错,必须是这样
    head = {
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48"
    }
    #这里就是利用urllib.request 来模拟信息
    request = urllib.request.Request(url, headers = head)
    html = ""
    #注意可能会错,记得处理异常
    try:
    	# urlopen 就是用来发送请求的,刚刚是设置请求信息
        response = urllib.request.urlopen(request)
        # 得到结果,并设置一下字符集,有中文
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
            
    return html #返回结果

finddata = re.compile(r"\"diff\":(.+?)}}")

    
def main():
	#url 就是我们复制下来的链接
    url = "http://31.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409351419538539436_1623731451797&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1623731452611"
    res = askURL(url) #去模拟 div1 向服务器发出请求
    print(res)
    
# 这是类似于 C 语言的写法,告诉程序从 main 函数开始执行,方便管理
if __name__ == "__main__": 
    main()

这部分代码的运行结果很明显,就是
在这里插入图片描述
这堆没缩进的 json 代码,到这里,我们已经获取到数据源码了
ps:这个内容是 print 出来的,执行结果不会跳转到网页的

解析数据

下边就开始处理这堆乱码了,其实很简单,用 json 这个包来处理即可(python yyds ! ! !)。
不过还是需要一下正则表达式的,百度自学即可。

import re
import urllib
import json
import time
import pymysql

def askURL(url):
    head = {
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48"
    }
    
    request = urllib.request.Request(url, headers = head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html

#正则表达式
finddata = re.compile(r"\"diff\":(.+?)}}")

def getData(url):
    #得到源码信息
    html = askURL(url)
    #用正则表达式得到元组内的信息
    data = re.findall(finddata, html)
    #把源码变成python对象,也就是可以下标操作
    jsonObj = json.loads(data[0])
    for item in jsonObj:
        print(item['f14'])

def main():
    
    url = "http://31.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409351419538539436_1623731451797&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1623731452611"
    
    getData(url)
    

if __name__ == "__main__":
    main()
   

这里来说一下这里的正则表达式,我们需要的是第九行 [ 到
在这里插入图片描述
第 649 行 ] 之间的内容(保护这对方括号),故而正则表达式为:“diff”:(.+?)}},注意标记的地方,这里是固定的,所以可以通过这两部分来得到中间 [ … ] 之间的内容。
在这里插入图片描述
再说说,json.loads(data[0]),就是把 json 源码变成一个 pyhton 的对象,其他的百度即可。data[0] 是一因为,我们知道正则表达式的匹配结果只有一个符合的

运行结果如下:
在这里插入图片描述
这里注意:print(item[‘f14’]),我们得到的 python对象是一个元组在这里插入图片描述
如果是其他地方,对应换即可,可以f15,f11…

到这里,我们就得到了真正的数据了
完结撒花★,°:.☆( ̄▽ ̄)/$:.°★

保存数据

下边不想多解释了,下次或者其他文章再写吧,给一个带注释的代码,
ps: 这里注意一下getData() 的变化

import re
import urllib
import json
import time
import pymysql

def askURL(url):
    head = {
        "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.101 Safari/537.36 Edg/91.0.864.48"
    }
    
    request = urllib.request.Request(url, headers = head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html

finddata = re.compile(r"\"diff\":(.+?)}}")

def getData(baseurl1, baseurl2):
    datalist = []
    j = 0
    for i in range(0, 1):
    	#这里就是计算真正的链接的地方,要翻页
        url = baseurl1 + str(i+1) + baseurl2
        html = askURL(url)
        data = re.findall(finddata, html)
        #print(data[0])
        jsonObj = json.loads(data[0])
        #我是把信息当作一个二维列表来存的,其他方式也行
        for item in jsonObj:
            datalist.append([])
            for i in range(1, 21):
                name = "f" + str(i)
                #爬下来的数据没有 f19 这个要注意处理一下
                if i == 19: datalist[j].append(" ")
                else: datalist[j].append(item[name])
            j = j + 1
        time.sleep(1)
        
    return datalist

# 数据库操作,写入库中,基本算是模板了,根据情况改循环和sql语句即可
def insertSQL(datalist):
    db = pymysql.connect(host="localhost",user="root",password="123456",\
                         db="test",port=3306,charset='utf8')
    cursor = db.cursor() 
    for itme in datalist:
        sql = "INSERT INTO data (id, name, now, Max, Min) VALUES (%s, %s, %s, %s, %s)"
        val = (str(itme[11]), str(itme[13]), str(itme[16]), str(itme[14]), str(itme[15]))
        cursor.execute(sql, val)
        db.commit()
    
    db.close()
    
def main():
	#最最前边说过了,pn是用来表示页码的变量
    baseurl1 = "http://31.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112409351419538539436_1623731451797&pn="
    baseurl2 = "&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1623731452611"
    data = getData(baseurl1, baseurl2)
    insertSQL(data)
    
if __name__ == "__main__":
    main()
    

最后

最后写的笼统了,要是哪里我没讲清楚,留言一下我来补充
最最后,如有错误,大佬轻喷~~

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值