页面内容的生成方式
动态页面区别于静态页面的最主要特征是页面内容的生成方式,动态页面的内容 生成方式可以分成两类,即服务端生成、客户端生成。
服务器端生成
Web内容管理系统,页面主要内容和页面的结构和表现方式分离。
Client/server/Database
脚本语言:jsp、asp、php等。
客户端生成
轻量级、局部的,例如给用户提示警告信息、显示定时时间等。
脚本语言: javascript、VBScript、ActionScript等
插件:Active X插件、Flash插件等
可能影响客户端安全。
动态网页经常使用的一种技术是Ajax请求技术。
Ajax = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML) 优点:在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页的内容。
实例所用链接:微博
实例所用浏览器:火狐
1.查找Ajax请求
- 以home开头的请求:空白框架,无实质内容
- 以config开头的请求:用于校验
- 以getIndex开头的请求
问题:我的找不到getIndex请求,是因为在主界面,没有进行任何操作,现在我点击进入
不断刷新网易云音乐下的内容,得到多个getIndex请求。
发现url的变换规律
变化的只有page的值,url由以下几部分组成。
2.查询JSON中信息
双击这里可以直接以json格式呈现
可以看出微博上的信息都在cards中,查看其中一个,里面含有微博正文,id,点赞数,转发量等等。
import json
import requests
from urllib.parse import urlencode
import re
from pyquery import PyQuery as pq # 这个库需要命令行pip 下载安装一下
'''
url分为四部分
1 https://m.weibo.cn/api/container/getIndex?
2 containerid=2304131721030997_-_WEIBO_SECOND_PROFILE_WEIBO
3 &page_type=03
4 &page=2
'''
# 构造请求
def get_page(i):
headers = {
'Host': 'm.weibo.cn',
'Referer': 'https://m.weibo.cn/profile/1721030997',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
'X-Requested-With': 'XMLHttpRequest'}
params={
'containerid':'2304131721030997_-_WEIBO_SECOND_PROFILE_WEIBO',
'page_type':'3',
'page':i
}
url = base_url + urlencode(params)
response = requests.get(url,headers = headers)
if response.status_code == 200:
print("访问成功")
return response.json()
return None
# 数据获取
def parse_page(source):
items = source.get('data').get('cards') # items类型为list
for item in items:
item = item.get('mblog') # item类型为dict
if item:
data = {
'id': item.get('id'),
'text': pq(item.get("text")).text(), # 仅提取内容中的文本
'attitudes': item.get('attitudes_count'),
'comments': item.get('comments_count'),
'reposts': item.get('reposts_count')
}
# 创建一个字典存放内容
yield data # 有yield说明为generator生成器
# if source:
# item1 = source['data']['cards']
# ids = []
# text = []
# for item in item1:
# item = item['mblog']
# id_ = item['id']
# text_ = item['raw_text']
# ids.append(id_)
# text.append(text_)
# dictioanary = dict(zip(ids,text))
# return dictioanary
if __name__=='__main__':
base_url = 'https://m.weibo.cn/api/container/getIndex?'
for i in range(2,5): # 我爬取的是第2,3,4页
source = get_page(i) # 请求url
# print(source)
results = parse_page(source)
for result in results: # 对于生成器来说,取出元素需要用循环
print(result)
这里解释一下生成器generator:
提到生成器,你可能会有一个简单的概念,如果函数里使用yield关键字,那么这个函数就是一个生成器,不同于return,生成器使用yield来返回值。
yield和return实质上区别非常大,最明显之处便在于,return 语句执行后,函数就退出了,而yield语句执行时,仅仅是返回一个值而已,不存在函数结束这个概念,因此生成器都要结合for循环进行使用。
更加细致的解释请点击这个链接,我觉得这两个博主解释得很好。
yield 理解
generator生成器