2022 年,把 Python 学得跟 Java 一样熟练—— 获取腾讯动漫信息

172 阅读2分钟

背景

昨天看了一篇获取房价的文章后,运行了案例代码,能看懂,但对 html 解析的用法还不熟悉。今天继续练习 Python 编码,目标网站是腾讯动漫,先完成基本信息的获取。

【某平台怎么都通不过审核,于是决定换个平台发该文】

页面元素分析

开发者模式,定位到一个节点: 在这里插入图片描述 根据 class 信息查询动漫节点,目标是具有ret-search-item clearfixli 元素。

动漫的各项信息定位:

  1. 海报地址:第一个 a 标签下的 img 标签的 data-original 属性。
  2. 动漫名称:第一个 a 标签的 titile 属性。
  3. 作者:具有 ret-works-author 类属性的 p 标签的文本。
  4. 描述:具有 ret-works-decs 类属性的 p` 标签的文本。
  5. 动漫详情地址:具有 ret-works-view 类属性的 a 标签的 href 属性。

编码实现

要取全部页面,考虑用多线程协作。

from bs4 import BeautifulSoup
import numpy as np
import requests
from requests.exceptions import RequestException
import threading

"--动漫网页方法--"
def spiderPage(url, page):
    try:
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36"}
        html1 = requests.request("GET", url, headers=headers, timeout=10)
        html1.encoding = 'utf-8'  # 加编码,重要!转换为字符串编码,read()得到的是byte格式的
        html = html1.text

        # print('scrawl result')
        # print(html)
        return html
    except RequestException:  # 异常捕获
        print('第{0}读取网页失败'.format(page))
        return None

"--解析列表页面的动漫信息--"
def parsePage(url, page):
    # 取页面
    html = spiderPage(url, page)
    html = str(html)
    if html is not None:
        # soup = BeautifulSoup(html, 'lxml')
        soup = BeautifulSoup(html, 'html.parser')
        "--先确定动漫信息,即li标签列表,li class = ret-search-item clearfix --"
        cosmics = soup.find_all("li",class_="ret-search-item clearfix")
        for j in range(len(cosmics)):  # 遍历每一个动漫
            cosmic = cosmics[j]

            "动漫海报:mod-cover-list-thumb mod-cover-effect ui-db"
            poster = cosmic.findNext("a")
            posterImgTag = poster.findNext("img")
            posterImgUrl = posterImgTag.get("data-original")
            print("posterImgUrl ",posterImgUrl)

            "动漫详情 URL"
            cosmicTag= cosmic.findNext("a",class_="ret-works-view")
            cosmicUrl = "https://ac.qq.com/"+ cosmicTag.get("href")

            "动漫名称:ret-works-title "
            print("name is", poster.get("title"))

            "动漫作者:ret-works-author"
            author = cosmic.findNext("p",class_="ret-works-author")
            print("author is ", author.text)

            "动漫描述:ret-works-decs"
            desc = cosmic.findNext("p",class_="ret-works-decs")
            print("desc is ",desc.text)
            print()

# 多线程爬虫
for i in range(1,100,2):  # 遍历网页1-101
    url1 = "https://ac.qq.com/Comic/index/page/" + str(i)
    url2 = "https://ac.qq.com/Comic/index/page/" + str(i + 1)

    t1 = threading.Thread(target=parsePage, args=(url1, i))  # 线程1
    t2 = threading.Thread(target=parsePage, args=(url2, i + 1))  # 线程2
    t1.start()
    t2.start()

运行结果

在这里插入图片描述

编码启示录

首先,有个大疑惑就是解析文本的时候, soup = BeautifulSoup(html, 'html.parser')soup = BeautifulSoup(html, 'lxml') 有什么区别呢?

最初参考房价项目的代码,用的是 lxml ,select 按 class 解析不到东西,再改成 html.parser 用 find 方法可以正常解析了。

答案是,解析器不同:

  • html.parser,内置,不需要额外的依赖项。
  • html5lib,最宽大,如果HTML损坏,最好使用它。
  • lxml,最快,依赖外部 C 。

其次,Python 解析页面还是挺好定位的。