爬虫爬取网站访问量_showDynClicks

爬虫爬取网站访问量_showDynClicks

一、背景

在爬取某个网站的信息时发现网站的访问量无法获取到,如下图所示:

可以看到阅读次数后面并不是一个数字,而是一个script。

但使用浏览器浏览网页的时候发现是能正常显示(url为http://www.dxsjs.sdu.edu.cn/info/1003/1913.htm),如下图所示:

可见,这个阅读次数2817并非初次访问网站时就能获取到的,而是后续渲染出来的。

所以,直接处理爬取到的html不能解决我们的问题,我们需要去看看这个2817到底是怎么来的。

打开开发者工具,刷新页面,在Fetch/XHR下面我们发现(好吧这会变成2818了):

可见这个阅读次数是异步请求到的,接下来我们就开始设法获取到这个数据。

二、思路

在多次刷新页面后,可以得出结论,对http://www.dxsjs.sdu.edu.cn/system/resource/code/news/click/dynclicks.jsp?clickid=1913&owner=1396647413&clicktype=wbnews

发出GET请求即可获取到数据,其中clickid和owner两个参数是变化的,clicktype是不变的。

而前两个参数的值恰恰就是前面看到的<script>中的两个值。

所以思路很明确了:先获取这个script,得到clickid和owner,然后据此对上面的url发送GET请求获取访问次数。

三、解法

1. 获取整个文档

base_url = 'http://www.dxsjs.sdu.edu.cn/'


def get_html(url):
    url = base_url + url
    response = requests.get(url)
    # 显式指定编码
    response.encoding = 'utf-8'
    return response.text

这段代码是获取整个html文档的,这里特别地显式指定编码为utf-8,如果不指定的话会出现乱码,这个需要据网站特性而定,不同网站可能编码不同。

2. 获取标签

以下是需要处理的html片段:

<div id="view_info">
发布时间:2024-05-10 15:47  作者: 来源:
     阅读次数:<script>_showDynClicks("wbnews", 1396647413, 1913)</script>
<span id="dynclicks_wbnews_1913_253" name="dynclicks_wbnews_1913_253">2819</span>次
</div>

 可知需要先获取id为view_info的div标签。

下面这个函数实现了获取这个标签的功能。

def get_info(fp):
    soup = BeautifulSoup(fp, 'lxml')
    info = soup.find(id="view_info")
    return info

 fp是html原文,lxml是解析器,注意这个需要额外安装。

当从网页上获取HTML内容时,通常会将其传递给BeautifulSoup对象来解析。

然后对这个BeautifulSoup对象使用find方法寻找我们想要的标签,指定id为view_info。

下图截取自BeautifulSoup4.12官方文档。

3. 获取两个参数

 下面这段代码可以获取两个参数:

def get_visits(info):
    script = info.find("script")
    match = re.search(r'_showDynClicks\("wbnews", (\d+), (\d+)\)', script.string)
    data1, data2 = match.groups()

原理是这样的,首先对上面获取到的<div id="view_info">标签再深入查找,寻找script标签。

如果print一下,可以看到获取到的script就是下面这个:
 

<script>_showDynClicks("wbnews", 1396647413, 1913)</script>

接下来我们需要把这两个参数提取出来,我们使用正则表达式。

re.search函数用于在整个字符串中搜索第一个与正则表达式匹配的内容。

反斜杠加小括号表达括号的字符,这是转义的意思。

'\('表示'('
'\)'表示')'

而后面的(\d+)则起捕获作用,它代表着由一个或多个数字构成的一个纯数字字符串。

然后通过match.groups()方法就可以将这两个(\d+)分别提取出来,data1就是1396647413,data2就是1913。

4. 获取访问次数

获取到两个参数之后,就可以通过构造requests请求的方式获取访问次数了:

def get_visits(info):
    script = info.find("script")
    match = re.search(r'_showDynClicks\("wbnews", (\d+), (\d+)\)', script.string)
    data1, data2 = match.groups()
    resulturl = base_url + 'system/resource/code/news/click/dynclicks.jsp?clickid={}&owner={}&clicktype=wbnews'.format(data2, data1)
    response = requests.get(resulturl)
    return int(response.text)

这里比较简单,就不多赘述了。

最后取int是因为返回的访问次数是一个字符串,而我希望以整型的方式去做后续处理。

四、全部代码

全部代码如下:

import re
from bs4 import BeautifulSoup
import requests

base_url = 'http://www.dxsjs.sdu.edu.cn/'


def get_html(url):
    url = base_url + url
    response = requests.get(url)
    # 显式指定编码
    response.encoding = 'utf-8'
    return response.text


def soup(fp):
    soup = BeautifulSoup(fp, 'lxml')
    info = soup.find(id="view_info")
    visits = get_visits(info)
    return {
    "content": soup.find_all("div", class_="v_news_content")[0].get_text(),
    "title": soup.find(id="view_title").get_text(),
    "date": info.get_text()[5:15],
    "visits": visits,
    }


def get_visits(info):
    print(info)
    script = info.find("script")
    print(script)
    match = re.search(r'_showDynClicks\("wbnews", (\d+), (\d+)\)', script.string)
    data1, data2 = match.groups()
    resulturl = base_url + 'system/resource/code/news/click/dynclicks.jsp?clickid={}&owner={}&clicktype=wbnews'.format(data2, data1)
    response = requests.get(resulturl)
    return int(response.text)


if __name__ == "__main__":
    res = soup(get_html("info/1003/1913.htm"))
    print(res)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值