一,准备工作。

工具:win10+Python3.6

爬取目标:爬取图中红色方框的内容。

原则:能在源码中看到的信息都能爬取出来。

信息表现方式:CSV转Excel。

二,具体步骤。

先给出具体代码吧:

  1. import requests
  2. import re
  3. from bs4 import BeautifulSoup
  4. import pandas as pd
  5.  
  6. def gethtml(url):
  7. try:
  8. r = requests.get(url,timeout = 30)
  9. r.raise_for_status()
  10. r.encoding = r.apparent_encoding
  11. return r.text
  12. except:
  13. return "It is failed to get html!"
  14.  
  15. def getcontent(url):
  16. html = gethtml(url)
  17. soup = BeautifulSoup(html,"html.parser")
  18. # print(soup.prettify())
  19. div = soup.find("div",class_="indent")
  20. tables = div.find_all("table")
  21.  
  22. price = []
  23. date = []
  24. nationality = []
  25. nation = [] #standard
  26. bookname=[]
  27. link = []
  28. score = []
  29. comment = []
  30. people = []
  31. peo = [] #standard
  32. author = []
  33. for table in tables:
  34. bookname.append(table.find_all("a")[1]['title']) #bookname
  35. link.append(table.find_all("a")[1]['href']) #link
  36. score.append(table.find("span",class_="rating_nums").string) #score
  37. comment.append(table.find_all("span")[-1].string) #comment in a word
  38.  
  39. people_info = table.find_all("span")[-2].text
  40. people.append(re.findall(r'\d+', people_info)) #How many people comment on this book? Note:But there are sublist in the list.
  41.  
  42. navistr = (table.find("p").string) #nationality,author,translator,press,date,price
  43. infos = str(navistr.split("/")) #Note this info:The string has been interrupted.
  44. infostr = str(navistr) #Note this info:The string has not been interrupted.
  45. s = infostr.split("/")
  46. if re.findall(r'\[', s[0]): # If the first character is "[",match the author.
  47. w = re.findall(r'\s\D+', s[0])
  48. author.append(w[0])
  49. else:
  50. author.append(s[0])
  51.  
  52. #Find all infomations from infos.Just like price,nationality,author,translator,press,date
  53. price_info = re.findall(r'\d+\.\d+', infos)
  54. price.append((price_info[0])) #We can get price.
  55. date.append(s[-2]) #We can get date.
  56. nationality_info = re.findall(r'[[](\D)[]]', infos)
  57. nationality.append(nationality_info) #We can get nationality.Note:But there are sublist in the list.
  58. for i in nationality:
  59. if len(i) == 1:
  60. nation.append(i[0])
  61. else:
  62. nation.append("中")
  63.  
  64. for i in people:
  65. if len(i) == 1:
  66. peo.append(i[0])
  67.  
  68. print(bookname)
  69. print(author)
  70. print(nation)
  71. print(score)
  72. print(peo)
  73. print(date)
  74. print(price)
  75. print(link)
  76.  
  77. # 字典中的key值即为csv中列名
  78. dataframe = pd.DataFrame({'书名': bookname, '作者': author,'国籍': nation,'评分': score,'评分人数': peo,'出版时间': date,'价格': price,'链接': link,})
  79.  
  80. # 将DataFrame存储为csv,index表示是否显示行名,default=True
  81. dataframe.to_csv("C:/Users/zhengyong/Desktop/test.csv", index=False, encoding='utf-8-sig',sep=',')
  82.  
  83. if __name__ == '__main__':
  84. url = "https://book.douban.com/top250?start=0" #If you want to add next pages,you have to alter the code.
  85. getcontent(url)

1,爬取大致信息。

选用如下轮子:

  1. import requests
  2. import re
  3. from bs4 import BeautifulSoup
  4.  
  5. def gethtml(url):
  6. try:
  7. r = requests.get(url,timeout = 30)
  8. r.raise_for_status()
  9. r.encoding = r.apparent_encoding
  10. return r.text
  11. except:
  12. return "It is failed to get html!"
  13.  
  14. def getcontent(url):
  15. html = gethtml(url)
  16. bsObj = BeautifulSoup(html,"html.parser")
  17.  
  18. if __name__ == '__main__':
  19. url = "https://book.douban.com/top250?icn=index-book250-all"
  20. getcontent(url)

这样就能从bsObj获取我们想要的信息。

2,信息具体提取。

所有信息都在一个div中,这个div下有25个table,其中每个table都是独立的信息单元,我们只用造出提取一个table的轮子(前提是确保这个轮子的兼容性)。我们发现:一个div父节点下有25个table子节点,用如下方式提取:

  1. div = soup.find("div",class_="indent")
  2. tables = div.find_all("table")

书名可以直接在节点中的title中提取(原始代码确实这么丑,但不影响):

  1. <a href="https://book.douban.com/subject/1770782/" onclick="&quot;moreurl(this,{i:'0'})&quot;" title="追风筝的人">
  2. 追风筝的人
  3.  
  4. </a>

据如下代码提取:

  1. bookname.append(table.find_all("a")[1]['title']) #bookname

相似的不赘述。

评价人数打算用正则表达式提取:

  1. people.append(re.findall(r'\d+', people_info)) #How many people comment on this book? Note:But there are sublist in the list.
  1. people_info = 13456人评价。
    在看其余信息:
  1. <p class="pl">[美] 卡勒德·胡赛尼 / 李继宏 / 上海人民出版社 / 2006-5 / 29.00元</p>

其中国籍有个“【】”符号,如何去掉?第一行给出回答。

  1. nationality_info = re.findall(r'[[](\D)[]]', infos)
  2. nationality.append(nationality_info) #We can get nationality.Note:But there are sublist in the list.
  3. for i in nationality:
  4. if len(i) == 1:
  5. nation.append(i[0])
  6. else:
  7. nation.append("中")

其中有国籍的都写出了,但是没写出的我们发现都是中国,所以我们把国籍为空白的改写为“中”:

  1. for i in nationality:
  2. if len(i) == 1:
  3. nation.append(i[0])
  4. else:
  5. nation.append("中")

还有list中存在list的问题也很好解决:

  1. for i in people:
  2. if len(i) == 1:
  3. peo.append(i[0])

长度为1证明不是空序列,就加上序号填写处具体值,使变为一个没有子序列的序列。

打印结果如下图:

基本是我们想要的了。

然后写入csv:

  1. dataframe = pd.DataFrame({'书名': bookname, '作者': author,'国籍': nation,'评分': score,'评分人数': peo,'出版时间': date,'价格': price,'链接': link,})
  2.  
  3. # 将DataFrame存储为csv,index表示是否显示行名,default=True
  4. dataframe.to_csv("C:/Users/zhengyong/Desktop/test.csv", index=False, encoding='utf-8-sig',sep=',')

注意:如果没有加上encoding='utf-8-sig'会存在乱码问题,所以这里必须得加,当然你用其他方法也可。

最后一个翻页的问题,这里由于我没做好兼容性问题,所以后面的页码中提取信息老是出问题,但是这里还是写一下方法:

  1. for i in range(10):
  2. url = "https://book.douban.com/top250?start=" + str(i*25)
  3. getcontent(url)

注意要加上str。

效果图:

其实这里的效果图与我写入csv的传人顺序不一致,后期我会看看原因。

三,总结。

大胆细心,这里一定要细心,很多细节不好好深究后面会有很多东西修改。

Python爬虫爬取豆瓣读书的更多相关文章

  1. Python爬虫爬取豆瓣电影之数据提取值xpath和lxml模块

    工具:Python 3.6.5.PyCharm开发工具.Windows 10 操作系统.谷歌浏览器 目的:爬取豆瓣电影排行榜中电影的title.链接地址.图片.评价人数.评分等 网址:https:// ...

  2. python 爬虫&爬取豆瓣电影top250

    爬取豆瓣电影top250from urllib.request import * #导入所有的request,urllib相当于一个文件夹,用到它里面的方法requestfrom lxml impor ...

  3. Python爬虫-爬取豆瓣图书Top250

    豆瓣网站很人性化,对于新手爬虫比较友好,没有如果调低爬取频率,不用担心会被封 IP.但也不要太频繁爬取. 涉及知识点:requests.html.xpath.csv 一.准备工作 需要安装reques ...

  4. 2019-02-01 Python爬虫爬取豆瓣Top250

    这几天学了一点爬虫后写了个爬取电影top250的代码,分别用requests库和urllib库,想看看自己能不能搞出个啥东西,虽然很简单但还是小开心. import requests import r ...

  5. python爬虫-爬取豆瓣电影数据

    #!/usr/bin/python# coding=utf-8# 作者 :Y0010026# 创建时间 :2018/12/16 16:27# 文件 :spider_05.py# IDE :PyChar ...

  6. Python爬虫爬取豆瓣电影名称和链接,分别存入txt,excel和数据库

    前提条件是python操作excel和数据库的环境配置是完整的,这个需要在python中安装导入相关依赖包: 实现的具体代码如下: #!/usr/bin/python# -*- coding: utf ...

  7. Python爬虫-爬取豆瓣电影Top250

    #!usr/bin/env python3 # -*- coding:utf-8-*- import requests from bs4 import BeautifulSoup import re ...

  8. python爬虫:利用正则表达式爬取豆瓣读书首页的book

    1.问题描述: 爬取豆瓣读书首页的图书的名称.链接.作者.出版日期,并将爬取的数据存储到Excel表格Douban_I.xlsx中 2.思路分析: 发送请求--获取数据--解析数据--存储数据 1.目 ...

  9. python定时器爬取豆瓣音乐Top榜歌名

    python定时器爬取豆瓣音乐Top榜歌名 作者:vpoet mail:vpoet_sir@163.com 注:这些小demo都是前段时间为了学python写的,现在贴出来纯粹是为了和大家分享一下 # ...

随机推荐

  1. PMP知识点(五)——资源管理表示方法

    资源矩阵 最常用的为RACI责任矩阵 如下: 资源数据表: 即时间和资源类型的交叉表,是资源直方图的拓展: 资源甘特图: 一种是以任务为索引 一级目录为任务,二级目录为资源,横坐标为时间进度 一种是以 ...

  2. 转载:C++中堆和栈的区别

    C++中堆和栈的区别,自由存储区.全局/静态存储区和常量存储区     文章来自一个论坛里的回帖,哪个论坛记不得了!    在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和 ...

  3. asp.net core NLog将日志写到文件

    1.安装Nlog包 Install-Package NLog.Extensions.Logging -Pre 2.在项目添加nlog.config文件 2.1.nlog.config <?xml ...

  4. sonar6.7.2启动报错

    sonar6.7.2启动报错:错误信息如下: es.log java.lang.RuntimeException: can not run elasticsearch as rootsonar.log ...

  5. iview 非 template/render 标签转换

    在 非 template/render情形下使用 iview,发现除了官方的一些需要注意的点外,还有一些其他需要注意的,这里记录下,防踩坑: 官方说明: 在非 template/render 模式下( ...

  6. js创建1-100的数组

    //实现方法一:循环赋值var arr1 = new Array(100);for(var i=0;i<arr1.length;i++){ arr1[i] = i;}console.log(ar ...

  7. nginx跨域问题记录

    现象:访问 toolbox.chinasoft.com 提示如下:Access to Font at 'https://images.chinasoft.com/static-toolbox/styl ...

  8. mysql 从一个表查询数据插入另一个表或当前表

    mysql insert into 表明(uid,lng,lat) SELECT uuid,lng,lat FROM 表明

  9. python正则表达式--findall、finditer方法

    findall方法 相比其他方法,findall方法有些特殊.它的作用是查找字符串中所有能匹配的字符串,并以结果存于列表中,然后返回该列表 注意: match 和 search 是匹配一次 finda ...

  10. 【JS】Javascript数组操作

    1.提取数组中每个对象的某个属性组成新的数组 如数组为: let arry = [ { name: 'zhao', 'age': 18 }, { name: 'qian', 'age': 19 }, ...