我们已经准备好了,你呢?

我们与您携手共赢,为您的企业形象保驾护航!

大家好,我是东眠的鱼,专注原创,致力于用浅显易懂的语言分享爬虫、数据分析及可视化等干货,希望人人都能学到新知识。<文末附带精品籽料哦,也可以和博主一起学Python呀!>

项目背景

有同学自学爬虫时,发现翻页的时候,url一直不变。其实他爬取的是较高难度的网页——动态网页。今天给大家介绍动态网页的爬虫!

AJAX动态加载网页

一、什么是动态网页

所谓的动态网页,是指跟静态网页相对的一种网页编程技术。静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。而动态网页则不然,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。——来源百度百科

动态网页具有减少工作量、内容更新快、可完成功能多等特点,被很多公司所采用,比如狗东、某宝、某瓣、某乎等等。

二、什么是AJAX

随着人们对动态网页加载速度的要求越来越高,AJAX技术应运而生并成为许多站点的首选。AJAX是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着在不重新加载整个网页的情况下,可以对网页的某部分进行更新。

三、如何爬取AJAX动态加载网页

1. 解析接口

只要是有数据发送过来,那肯定是有发送到服务器的请求的吧。我们只需找出它悄悄加载出的页面的真实请求即可。特点:爬取速度快,爬取的数据干净,有些网站解析难度较大。

2. Selenium

selenium是什么呢?它本来是个自动化测试工具,但是被广泛的用户拿去爬虫了。它是一个工具,这个工具可以用代码操作浏览器,比如控制浏览器的下滑、模拟鼠标点击等。特点:代码较简单,爬取速度慢,容易被封ip。

项目实操

怎么说了那么多理论,说实话也不想那么啰嗦。可是吧,这些东西经常会被问到,干脆直接写下来,下次还有人问就直接把这篇文章发给他,一劳永逸!

我们拿一个法院信息公示网页举例:

那我们就开启爬虫的正确姿势吧,先用解析接口的方法来写爬虫。

首先,找到真实请求。右键检查,点击Network,选中XHR,刷新网页,选择Name列表中的jsp文件。没错,就这么简单,真实请求就藏在里面。

我们再仔细看看这个jsp,这简直是个宝啊。有真实请求url,有请求方法post,有Headers,还有Form Data,而From Data表示给url传递的参数,通过改变参数,咱们就可以获得数据!

我们再仔细看看这些参数,pagesnum参数不就是代表页数嘛!我们尝试点击翻页,发现只有pagesnum参数会变化。

既然发现了它,那就赶紧抓住它。打开PyCharm,导入了爬虫所需的库。

1from urllib.parse import urlencode   2import csv   3import random   4import requests   5import traceback   6from time import sleep   7from lxml import etree    #lxml为第三方网页解析库,强大且速度快    

构造真实请求,添加Headers。

 1base_url = 'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search_content.jsp?'  #这里要换成对应Ajax请求中的链接    2    3headers = {    4    'Connection': 'keep-alive',    5    'Accept': '*/*',    6    'X-Requested-With': 'XMLHttpRequest',    7    'User-Agent': '你的User-Agent',    8    'Origin': 'http://www.hshfy.sh.cn',    9    'Referer': 'http://www.hshfy.sh.cn/shfy/gweb2017/ktgg_search.jsp?zd=splc',   10    'Accept-Language': 'zh-CN,zh;q=0.9',   11    'Content-Type': 'application/x-www-form-urlencoded',   12    'Cookie': '你的Cookie'   13} 

构建get_page函数,自变量为page,也就是页数。以字典类型创建表单data,用post方式去请求网页数据。这里要注意要对返回的数据解码,编码为’gbk’,否则返回的数据会乱码!另外我还加了异常处理优化了下,以防意外发生。

 1def get_page(page):    2    n = 3    3    while True:    4        try:    5            sleep(random.uniform(1, 2))  # 随机出现1-2之间的数,包含小数    6            data = {    7                'yzm': 'yxAH',    8                'ft':'',    9                'ktrqks': '2020-05-22',   10                'ktrqjs': '2020-06-22',   11                'spc':'',   12                'yg':'',   13                'bg':'',   14                'ah':'',   15                'pagesnum': page   16            }   17            url = base_url + urlencode(data)   18            print(url)   19            try:   20                response = requests.request("POST",url, headers = headers)   21                #print(response)   22                if response.status_code == 200:   23                    re = response.content.decode('gbk')   24                    # print(re)   25                    return re  # 解析内容   26            except requests.ConnectionError as e:   27                print('Error', e.args)  # 输出异常信息   28        except (TimeoutError, Exception):   29            n -= 1   30            if n == 0:   31                print('请求3次均失败,放弃此url请求,检查请求条件')   32                return   33            else:   34                print('请求失败,重新请求')   35                continue 

构建parse_page函数,对返回的网页数据进行解析,用Xpath提取所有字段内容,保存为csv格式。有人会问为这么喜欢用Xpath,因为简单好用啊!!!

 1def parse_page(html):    2    try:    3        parse = etree.HTML(html)  # 解析网页    4        items = parse.xpath('//*[@id="report"]/tbody/tr')    5        for item in items[1:]:    6            item = {    7                'a': ''.join(item.xpath('./td[1]/font/text()')).strip(),    8                'b': ''.join(item.xpath('./td[2]/font/text()')).strip(),    9                'c': ''.join(item.xpath('./td[3]/text()')).strip(),   10                'd': ''.join(item.xpath('./td[4]/text()')).strip(),   11                'e': ''.join(item.xpath('./td[5]/text()')).strip(),   12                'f': ''.join(item.xpath('./td[6]/p/text()')).strip(),   13                'g': ''.join(item.xpath('./td[7]/p/text()')).strip(),   14                'h': ''.join(item.xpath('./td[8]/text()')).strip(),   15                'i': ''.join(item.xpath('./td[9]/text()')).strip()   16            }   17            #print(item)   18            try:   19                with open('./law.csv', 'a', encoding='utf_8_sig', newline='') as fp:   20                    # 'a'为追加模式(添加)   21                    # utf_8_sig格式导出csv不乱码   22                    fieldnames = ['a', 'b', 'c', 'd', 'e','f','g','h','i']   23                    writer = csv.DictWriter(fp,fieldnames)   24                    writer.writerow(item)   25            except Exception:   26                print(traceback.print_exc())  #代替print e 来输出详细的异常信息   27    except Exception:   28        print(traceback.print_exc()) 

最后,遍历一下页数,调用一下函数。OK,搞定!

1    for page in range(1,5):  #这里设置想要爬取的页数   2        html = get_page(page)   3        #print(html)   4        print("第" + str(page) + "页提取完成")    

我们来看一下最终效果:

结 语

总结一下,对于AJAX动态加载网页爬虫,一般就两种方式:解析接口;Selenium。这次就先介绍了解析接口方式,个人还是推荐解析接口的方式,如果解析的是json数据,就更好爬了。实在没办法了再用Selenium吧。

最后 如果你对Python感兴趣的话,可以试试我整理的这份Python全套学习资料,【点击这里】领取!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!
Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独特的Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便******

  • 免责声明:本站内容(文字信息+图片素材)来源于互联网公开数据整理或转载,仅用于学习参考,如有侵权问题,请及时联系本站删除,我们将在5个工作日内处理。联系邮箱:chuangshanghai#qq.com(把#换成@)

    我们已经准备好了,你呢?

    我们与您携手共赢,为您的企业形象保驾护航!

    在线客服
    联系方式

    热线电话

    132-7207-3477

    上班时间

    周一到周五

    二维码
    线