Python爬虫——爬取知乎(实践)

python爬虫 专栏收录该内容
1 篇文章 0 订阅
  • 今天开始看另外一本网络爬虫的书。发现有好多内容重复了,所以跳着看了看。然后发现了一个书后的实战示例。
  • 给书后一个评价:这什么玩意!最后还是用了我自己的方法来实现对于这个知乎直播部分的爬取。
  • 今天顺着昨天的思路,首先看了看这个网页。发现:这个网页挺好的,返回回来的时候,直接就是完整的网页,这可算是省了很多的力气。
https://api.zhihu.com/lives/homefeed?includes=live
  • 所有关于直播板块的数据都存放在这个url中,直接提出之后,就可以进行访问。
  • 但是,尝试了一个之后,又发现问题了

image.png

  • 这样的一个页面,完整显示的数据,就直到讲座作者就完事了!然后那些个评论数据又是放在一个url里。好无语啊!
  • 后来终于在三级页面里找到了请求的这个网址,而且这个网址用于请求的属性,并不算难。本以为其中的sku_id属性用于表示的是原来的用户ID。其实这个评论的属性另有文章。
  • 太生气了,搞这么复杂。通过比对,发现了这个不同,我想应该存在于网页中的某个位置,因为在请求中,没有什么额外的请求。果然,在一堆的textarea中找到了这个属性。这个json复杂程度令人发指!

QQ截图20201215124900.png

  • 最后还是提取出来,然后做了改造。
  • 示例代码
import csv
import json
import os

import requests
from bs4 import BeautifulSoup


def Collect():
    with open("../files/知乎.csv", "r", encoding='UTF-8') as csvfile:
        reader = csv.DictReader(csvfile)
        for row in reader:
            # 获取每个评论中的id号
            id = row["id"]
            # 这是一个直播模块的网址,用于参考。
            # https: // www.zhihu.com / lives / 919165878388535296
            tempUrl = "https://www.zhihu.com/lives/" + id
            print(tempUrl)
            html = requests.get(url=tempUrl, headers=header)
            bsObj = BeautifulSoup(html.content, 'lxml', from_encoding='utf-8')
            # html = urlopen(tempUrl)
            # bsObj = BeautifulSoup(html, 'html.parser')
            # 找到这个论坛的创始人的标签
            Writer = bsObj.find("div", {"class": "UserCell-name-hzEyq"}).get_text()
            print("Writer:", Writer, '\n')
            # 查找到含有评论网页json的sku_id号
            TextArea = bsObj.find("textarea", {"id": "resolved"}).get_text()
            Json = json.loads(TextArea)
            sku_id = Json["appContext"]["__connectedAutoFetch"]["liveDetailsNew"]["data"]["skuGrading"]["sku_id"]
            print(sku_id)
            # 如果不存在这个文件,就要创建一个项目
            tempFileName = os.path.dirname("../files/" + id + ".csv")
            if not os.path.exists(tempFileName):
                os.makedirs(tempFileName)
            tempCsvFile = open("../files/" + id + ".csv", 'wt', newline='', encoding='utf-8')
            writer = csv.DictWriter(tempCsvFile, fieldnames=['author', 'comment'])

            # https://api.zhihu.com/darwin/hot_reviews?sku_id=969583563645173760&limit=10&offset=0
            commentUrl = "https://api.zhihu.com/darwin/hot_reviews?sku_id=" + sku_id + "&limit=10&offset=0"
            comment_res = requests.get(url=commentUrl, headers=header)
            for item in comment_res.json()["data"]:
                author = item["author"]["name"]
                comment = item["content"]
                print(author, ":", comment)
                writer.writerow({"author": author, "comment": comment})
            tempCsvFile.close()


if __name__ == '__main__':
    # 将知乎直播模块的url网址存放进url变量中,将请求头设置完成
    url = "https://api.zhihu.com/lives/homefeed?includes=live"
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"
    }
    # 发送请求
    response = requests.get(url=url, headers=header)

    print(response.text)

    # 设定一个用于存储讨论课题和id号的文件
    fileUrl = os.path.dirname("../files/知乎.csv")
    # 如果不存在这个文件,就要创建一个项目
    if not os.path.exists(fileUrl):
        os.makedirs(fileUrl)
    csvFile = open("../files/知乎.csv", 'wt', newline='', encoding='utf-8')
    writer = csv.DictWriter(csvFile, fieldnames=['title', 'id'])
    # 写入列标题,即DictWriter构造方法的fieldnames参数
    writer.writeheader()

    for item in response.json()["data"]:
        id = item["live"]["id"]
        title = item["live"]["subject"]
        print(id, ":" + title)
        writer.writerow({'title': title, 'id': id})
    csvFile.close()
    Collect()
  • 这里面,提供了两种BeautifulSoup解析的方式。调查了一下,主要是因为request.get返回的对象,和urlopen返回的对象不一样。request要使用lxml的解析器,而urlopen只需要使用html的解析器即可。
  • 然后今天也对csv文件进行了一个进一步的拓展学习。可以发现,之前就是直接写,今天进行了一个改进,就是对格式进行了调整。

不足之处

  • 主要就是最近读了代码整洁之道。我觉得这一段代码,就很不美。但是也是爬虫初学者。我之后会注意这方面的问题。尽量将方法普遍化。
  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值