大师兄的Python学习笔记(二十三): 爬虫(四)

大师兄的Python学习笔记(二十二): 爬虫(三)
大师兄的Python学习笔记(二十四): 爬虫(五)

五、爬取Ajax数据

  • 为了实现前后端分离,越来越多的网站使用Ajax制作动态页面。
  • 在这种情况下,原始页面获取不到有效数据,需要模拟Ajax请求获取数据。
1. 关于Ajax
  • Ajax即异步的JavaScript和XML(Asynchronous JavaScript and XML), 是一种创建交互式网页应用的网页开发技术。
  • Ajax利用JS实现在页面不刷新,链接不改变的情况下与服务器交换数据并更新部分网页的能力。
  • 前台:HTML + JS + AJAX


  
    
    sample
    
  
  
    
  • 后台:xml


    
        HelloWorld from server!
    

  • 效果


2. 观察Ajax请求
  • Ajax请求的类型为XHR,在header中可以找到x-requested-with: XMLHttpRequest
  • 打开浏览器 -> 打开网页 -> 按f12 - > 切换到netword选项卡 -> 切换到xhr子选项卡 -> 触发Ajax- > 获得请求
  • 以头条网搜索(https://www.toutiao.com/search)为例。
    大师兄的Python学习笔记(二十三): 爬虫(四)_第1张图片
  • 通过观察请求内容,可以获得请求的url和参数。


4. 爬取Ajax数据
  • 用Python模拟浏览器发出Ajax请求:
>>>import requests
>>>from urllib.parse import urlencode

>>>base_url = 'https://www.toutiao.com/api/search/content/?'
>>>headers={
>>>    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
>>>    'x-Requested-With':'XMLHttpRequest'
>>>}

>>>def get_page():
>>>    # 获取ajax数据
>>>    params = {
>>>        'aid':'24',
>>>        'app_name':'web_search',
>>>        'offset':'0',
>>>        'format':'json',
>>>        'keyword':'天问',
>>>        'autoload':'true',
>>>        'count':'20',
>>>        'en_qc':'1',
>>>        'cur_tab':'1',
>>>        'from':'search_tab',
>>>        'pd':'synthesis',
>>>        'timestamp':'1595555856284',
>>>        '_signature':'dmnSBgAgEBCwPmuLZGUZj3ZokxAACl20erea8yVotjl6bt0QyPm3C0IitmjZPdNLeqVl - m. - Anc.JeDoNUPwmgSxIQAjLH87GiPqebGl3ewifL.FLPgoxpud29vpujvqaIt'
>>>    }
>>>    url = base_url + urlencode(params)
>>>    try:
>>>        response = requests.get(url,headers=headers)
>>>        if(response.status_code == 200):
>>>            return response.json()
>>>    except requests.ConnectionError as e:
>>>        print('Error',e.args)

>>>if __name__ == '__main__':
>>>    data = get_page()
>>>    print(len(data))
26
  • 解析数据:
>>>import requests
>>>from urllib.parse import urlencode

>>>base_url = 'https://www.toutiao.com/api/search/content/?'
>>>headers={
>>>    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
>>>    'x-Requested-With':'XMLHttpRequest'
>>>}

>>>def parse_page(func):
>>>    # 解析数据
>>>    def deco(*args, **kwargs):
>>>        data = filter(lambda x:x.get('abstract'),func(*args, **kwargs).get('data')) # 获取并过滤数据
>>>        result = []
>>>        for d in data:
>>>            message = {}
>>>            message['title'] = d.get('title')
>>>            message['from'] = d.get('media_name')
>>>            message['datetime'] = d.get('datetime')
>>>            message['read_count'] = d.get('read_count')
>>>            result.append(message)
>>>        return result
>>>    return deco

>>>@parse_page
>>>def get_page():
>>>    # 获取ajax数据
>>>    params = {
>>>        'aid':'24',
>>>        'app_name':'web_search',
>>>        'offset':'0',
>>>        'format':'json',
>>>        'keyword':'天问',
>>>        'autoload':'true',
>>>        'count':'20',
>>>        'en_qc':'1',
>>>        'cur_tab':'1',
>>>        'from':'search_tab',
>>>        'pd':'synthesis',
>>>        'timestamp':'1595555856284',
>>>        '_signature':'dmnSBgAgEBCwPmuLZGUZj3ZokxAACl20erea8yVotjl6bt0QyPm3C0IitmjZPdNLeqVl - m. - Anc.JeDoNUPwmgSxIQAjLH87GiPqebGl3ewifL.FLPgoxpud29vpujvqaIt'
>>>    }
>>>    url = base_url + urlencode(params)
>>>    try:
>>>        response = requests.get(url,headers=headers)
>>>        if(response.status_code == 200):
>>>            return response.json()
>>>    except requests.ConnectionError as e:
>>>        print('Error',e.args)

>>>if __name__ == '__main__':
>>>    data = get_page()
>>>    for index,value in enumerate(data):
>>>        print(f'第{index}条 标题:<<{value.get("title")}>> 媒体:{value.get("from")} 日期:{value.get("datetime")} 阅读量:{value.get("read_count")} ')
第0条 标题:<<屈原的天问及译文>> 媒体:律界诗者 日期:2020-07-23 21:14:28 阅读量:181 
第1条 标题:<<上古奇文《天问》原文,屈原向上苍叩问宇宙本源>> 媒体:水煮歷史 日期:2018-10-24 14:21:55 阅读量:6850 
第2条 标题:<<千古奇文:屈原《楚辞》中的《天问》>> 媒体:泽光书院 日期:2020-05-01 19:43:47 阅读量:491 
第3条 标题:<<火星探测器为什么取名“天问”?第一时间解读火星探索 4 大问题>> 媒体:科学声音 日期:2020-07-24 10:27:47 阅读量:18 
第4条 标题:<<屈原《天问》原文与释文>> 媒体:书画鉴赏典评收藏 日期:2019-05-04 21:05:38 阅读量:835 
第5条 标题:<<天问一号成功发射,马斯克发推祝贺:令人惊叹>> 媒体:观察者网 日期:2020-07-23 18:01:08 阅读量:7764 
第6条 标题:<<中国历史性一天!火星探测器“天问一号”发射成功,领先美国>> 媒体:智东西 日期:2020-07-23 14:03:21 阅读量:9509 
第7条 标题:<<中国首次火星探测任务“天问一号”探测器成功发射,马斯克发推:令人惊叹>> 媒体:环球网 日期:2020-07-23 20:00:44 阅读量:1718 

参考资料


  • https://blog.csdn.net/u010138758/article/details/80152151 J-Ombudsman
  • https://www.cnblogs.com/zhuluqing/p/8832205.html moisiet
  • https://www.runoob.com 菜鸟教程
  • http://www.tulingxueyuan.com/ 北京图灵学院
  • http://www.imooc.com/article/19184?block_id=tuijian_wz#child_5_1 两点水
  • https://blog.csdn.net/weixin_44213550/article/details/91346411 python老菜鸟
  • https://realpython.com/python-string-formatting/ Dan Bader
  • https://www.liaoxuefeng.com/ 廖雪峰
  • https://blog.csdn.net/Gnewocean/article/details/85319590 新海说
  • https://www.cnblogs.com/Nicholas0707/p/9021672.html Nicholas
  • https://www.cnblogs.com/dalaoban/p/9331113.html 超天大圣
  • https://blog.csdn.net/zhubao124/article/details/81662775 zhubao124
  • https://blog.csdn.net/z59d8m6e40/article/details/72871485 z59d8m6e40
  • 《Python学习手册》Mark Lutz
  • 《Python编程 从入门到实践》Eric Matthes
  • 《Python3网络爬虫开发实战》崔庆才

本文作者:大师兄(superkmi)

你可能感兴趣的:(大师兄的Python学习笔记(二十三): 爬虫(四))