Python 爬虫分析豆瓣 TOP250 之 信息字典 和 马斯洛的锥子

问题

本文是对《Python 爬虫分析豆瓣 TOP250 告诉你程序员业余该看什么书?》 一文的补充

我们以《追风少年》为例

在这里插入图片描述
用chrome的developer tool查看源代码
在这里插入图片描述
这里发现,源代码的HTML比较难以分析(Parse)。

在原作者的文中,把这些都放在了一起。

[美] 卡勒德·胡赛尼 / 李继宏 / 上海人民出版社 / 2006-5 / 29.00元

而这样并不能满足我的要求(知识图谱)。

一开始,我也尝试着用xpath里面的sibling, next等去抓信息,但是都失败了。后来恍然大悟。其实,如果单单从页面上看,这明明就是key value pair,用冒号隔开。于是,我直接把字符串抓出来,很容易就搞定了。

信息字典

理想情况下,抓出来的信息是这个样子的。

作者:  [美] 卡勒德·胡赛尼 
出版社: 上海人民出版社
出品方: 世纪文景
原作名: The Kite Runner
译者:  李继宏 
出版年: 2006-5
页数: 362
定价: 29.00元
装帧: 平装
丛书: 卡勒德·胡赛尼作品
ISBN: 9787208061644

这样,一行行分析就行了。

但实际上,抓出来的信息是这样的

作者: 
        
                [美]
            卡勒德·胡赛尼

出版社: 上海人民出版社
出品方: 世纪文景
原作名: The Kite Runner
译者: 
        
            李继宏

出版年: 2006-5
页数: 362
定价: 29.00元
装帧: 平装
丛书: 卡勒德·胡赛尼作品
ISBN: 9787208061644

不过,也没关系,用正则表达式抓到所有的key。这样key之间的就是value了。

具体代码如下。(python 3.7)

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 27 12:08:08 2019

@author: eric
"""

import requests
from lxml import etree
from bs4 import BeautifulSoup
import time
import re

class Douban_Book():
    url = ""
    title_cn=""
    title_original="" #原作名
    author=""
    author_profile = ""
    publisher="" #出版社
    publish_date=""
    pages=""
    price=""
    series=""
    isbn=""
    rating = 0.0
    votes = 0
    summary = ""
    

HEADERS = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}

def get_urls():
    #https://book.douban.com/top250?start=225
    url_base = "https://book.douban.com/top250?start="
    urls = [url_base+str(i*25) for i in range(10)]
    return urls

def get_dict_value(the_dict, key, defualt_value=""):
    if key in the_dict:
        return the_dict[key]
    return defualt_value

def get_book(book_url):
    response = requests.request("get", book_url, headers=HEADERS)
    soup = BeautifulSoup(response.text, "html.parser")
    
    book = Douban_Book()
    book.url = book_url
    book.title_cn = soup.find("h1").text.strip()
    
    #以下是信息字典
    soup_info = soup.find("div",{"id":"info"})
    info_text = soup_info.text
    heads = re.findall("\n.+:",info_text)
    info_dict = {}
    for i in range(len(heads)-1):
        start_at=info_text.find(heads[i])+len(heads[i])
        end_at=info_text.find(heads[i+1])
        value = info_text[start_at:end_at].strip().replace("\n","")
        value = re.sub("\s+"," ",value)
        key = heads[i].strip().replace(":","")
        info_dict[key]=value
    #the last key value pair
    start_at=info_text.find(heads[-1])+len(heads[-1])
    value = info_text[start_at:].strip().replace("\n","")
    key = heads[-1].strip().replace(":","")
    info_dict[key]=value
    
    #把信息字典里的信息写入book对象
    book.author = get_dict_value(info_dict, "作者")
    book.isbn = get_dict_value(info_dict, "ISBN")
    book.pages = get_dict_value(info_dict, "页数")
    book.price = get_dict_value(info_dict, "定价")
    book.publish_date = get_dict_value(info_dict, "出版年")
    book.publisher = get_dict_value(info_dict, "出版社")
    book.series = get_dict_value(info_dict, "丛书")
    book.title_original = get_dict_value(info_dict, "原作名")
    #豆瓣评分
    book.rating = float(soup.find("strong",{"class":"ll rating_num "}).text.strip())
    #<span property="v:votes">405241</span>
    book.votes = int(soup.find("span",{"property":"v:votes"}).text)
    #简介
    intros = soup.find_all("div",{"class":"intro"})
    for p in intros[0].find_all("p"):
        book.summary+=p.text+"\r\n"
    for p in intros[1].find_all("p"):
        book.author_profile+=p.text+"\r\n"
    return book
    

def save_book(book):
    print("saving book {0} {1}".format(book.title_cn, book.title_original))
    pass

#https://book.douban.com/top250?start=0
def parse_list(list_url):
    response = requests.request("get", list_url, headers=HEADERS)
    tree = etree.HTML(response.text)
    trs=tree.xpath("//tr[@class='item']")
    for tr_item in trs:
        book_url=tr_item.xpath("descendant::a[1]/@href")[0]
        book = get_book(book_url)
        save_book(book)
        
    
def main():
    
    urls = get_urls()
    for url in urls[:1]:
        parse_list(url)
    
    time.sleep(1.1)

马斯洛的锥子

有时候,我们用惯了爬虫工具,会陷进爬虫工具的牛角尖里面。或者说,「如果你有的只是一個錘子,那麼所有的東西看起來都像一個釘子」 – Abraham Maslow。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

织网者Eric

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值