今天要做的是一个爬取当当网畅销书排行的爬虫,之后想看排行直接运行程序就可以看到啦,没有多余的信息,是不是很给力!

在前两次的爬虫编写过程中,思想都是把整个HTML文档看做一个很长很长的字符串,通过编写特定的正则表达式匹配我们需要的内容。这对于一般的内容不多的爬取需求是可以满足,但是一旦我们需要爬取的内容多了起来,正则表达式的模式就会变得相当复杂,可读性也不够好。那么有没有另外一种方法呢?答案是肯定的,这就是BeautifulSoup这个第三方库。

那么BeautifulSoup是做什么的呢?关于其详细功能,参阅官方文档,点击打开链接,这里只给出其主要思想:

Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。Beautiful Soup会帮你节省数小时甚至数天的工作时间。

简单来讲,Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,通过对这些对象进行操作,就可以得到需要的内容。

另外,稍微提一下,该实例获取指定url的html文档使用了requests库,其原理和urllib.request类似:

user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url, headers=headers)
html = r.text

得到一个html后,就可以使用soup = BeautifulSoup(html, 'html.parser'),得到解析后的BeautifulSoup对象soup,可以对soup进行操作获取指定内容。

好了,具体的用法还是参考上面的官方文档,先步入正题,编写今天的爬虫吧:

1.首先,进入到当当图书畅销榜的网页当当图书近24小时畅销榜,右键查看源代码,找到我们关心的排行榜的位置:

这里我们关心的有:排名,书名,评论,作者,出版日期,出版社,价格。而这些信息都在特定的标签内,通过soup对象的方法方便将其一一找到。

2.根据网页源代码,所有的榜单内的图书信息均在<ul class="bang_list clearfix bang_list_mode"></ul>标签内,这是我们关心的内容。在<ul></ul>标签下,每个榜单内的图书都在<li></li>标签下,具体信息对应相应的div标签。以排名信息为例,排名在标签<div class="list_num red">(排名前四的数字是红色的)和<div class="list_num">里,因此使用正则表达式匹配'class'属性,其中list_num$表示属性值以list_num字符串开头。这样就找到了所有的排名的div标签,之后调用标签的get_text()方法即可得到排名的字符串。代码如下:

def getBookInfo(html, lst):soup = BeautifulSoup(html, 'html.parser')tag_ul = soup.find('ul', attrs={'class': 'bang_list clearfix bang_list_mode'})tag_li = tag_ul.find_all('li')for book in tag_li:book_info = {}book_rank = book.find('div', attrs={'class': re.compile('list_num$')}).....book_info.update({'排名': book_rank.get_text()[:-1]}).....lst.append(book_info)return lst

获取其它图书信 息的代码类似,这里就不再一一说明,详见后面的完整代码。^_^

这里定义一个获取图书信息的函数,传入一个html和一个列表,每个图书的信息将使用字典类型存储,方便读取。调用字典的update({key:value})方法即可将键值对保存在字典中。利用for循环,每一个图书信息都保存完毕后,把代表这个图书的字典保存在lst中并返回,最后的得到的就是[{book1},{book2},....]。

3.保存文件

由于爬取的每本书包含的键都是相同的,因此将得到的列表保存在csv表格文件中比较清晰,也便于以后进行进一步的分析。python自带的csv库就可以解决这个问题,把数据写入csv文件的一般方法为:

user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url, headers=headers)
html = r.text

这里需要解释的有:

(1)使用with open()方法,在读写完成后会自动关闭文件;

(2)参数path指的是文件的路径,'w'指的是操作文件的方法这里是写文件。而后面两个参数我开始是没有加的,最后出现了两个问题:encoding='utf-8'不加的话会出现'gbk'编码问题,具体产生原因百度就好;newline=""不加的话最后写入的表格中会有多余的空行。

(3)由于爬取过程中需要写入多行数据,最后爬取的内容是列表元素为字典的列表,恰好csv.DictWriter(file, fieldnames)就是写入字典类型的数据,因此选择这个方法写文件。dictWriter.writeheader()就是写表头的,这里就是['排名', '书名', '作者', '评论数', '出版日期', '出版社', '售价'],下面的数据一一对应。dictWriter.writerows(lst)接收以字典为元素的list,每个字典是一行。

4.爬取完整榜单

上述过程爬取了给定的url,即排行榜首页的url。观察地址栏,榜单有25页,url为'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-(1-25)',  

user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url, headers=headers)
html = r.text

这样就得到了所有的url信息,在这个循环下每次爬取一页,就可以爬取完整榜单。这里用print记录爬取的进度,出问题时也能及时发现。

def main():book_list = []fieldnames = ['排名', '书名', '作者', '评论数', '出版日期', '出版社', '售价']path = 'C:/Users/Administrator/Desktop/dangdangBookRank.csv'url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-'for page in range(1, 26):des_url = url + str(page)html = getHTMLText(des_url)book_list = getBookInfo(html, book_list)print('正在爬取第' + str(page) + '页......')saveCsvFile(path, book_list, fieldnames)

在main()函数里,定义一个全局变量book_list,每次循环结果都保存在这个list里面,最后就得到了所有图书信息。再调用saveCsvFile()方法,就可以把数据保存在csv文件里。
以下是完整代码:

import requests
from bs4 import BeautifulSoup
import re
import csvuser_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}# 获取指定网页的HTML内容
def getHTMLText(url):try:r = requests.get(url, headers=headers)r.raise_for_status()r.encoding = r.apparent_encodingreturn r.textexcept Exception as e:print(e)# 获取图书信息
def getBookInfo(html, lst):soup = BeautifulSoup(html, 'html.parser')tag_ul = soup.find('ul', attrs={'class': 'bang_list clearfix bang_list_mode'})tag_li = tag_ul.find_all('li')for book in tag_li:book_info = {}book_rank = book.find('div', attrs={'class': re.compile('list_num$')})book_name = book.find('div', attrs={'class': 'name'}).abook_comments = book.find('div', attrs={'class': 'star'}).abook_author = book.find_all('div', attrs={'class': 'publisher_info'})[0].a# 24页第5本书的作者是直接在<div></div>标签内的,因此做一个辅助变量,在出现异常时顶替book_author_sup = book.find_all('div', attrs={'class': 'publisher_info'})[0]book_publish_date = book.find_all('div', attrs={'class': 'publisher_info'})[1].spanbook_publish_company = book.find_all('div', attrs={'class': 'publisher_info'})[1].abook_price = book.find('div', attrs={'class': 'price'}).spanbook_info.update({'排名': book_rank.get_text()[:-1]})book_info.update({'书名': book_name.get_text()})book_info.update({'评论数': book_comments.get_text()[:-3]})try:book_info.update({'作者': book_author.get_text()})except:book_info.update({'作者': book_author_sup.get_text()})book_info.update({'出版日期': book_publish_date.get_text()})book_info.update({'出版社': book_publish_company.get_text()})book_info.update({'售价': book_price.get_text()[-5:]})lst.append(book_info)return lst# 保存csv文件的函数
def saveCsvFile(path, lst, fieldnames):# open函数注意两个问题:# 1.'gbk'乱码问题:指定编码,加上encoding='utf-8'# 2.写入的csv多空行问题:加上 newline=""with open(path, 'w', encoding='utf-8', newline="") as file:dictWriter = csv.DictWriter(file, fieldnames)dictWriter.writeheader()dictWriter.writerows(lst)def main():book_list = []fieldnames = ['排名', '书名', '作者', '评论数', '出版日期', '出版社', '售价']path = 'C:/Users/Administrator/Desktop/dangdangBookRank.csv'url = 'http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-'for page in range(1, 26):des_url = url + str(page)html = getHTMLText(des_url)book_list = getBookInfo(html, book_list)print('正在爬取第' + str(page) + '页......')saveCsvFile(path, book_list, fieldnames)main()

当然还有最后的文件截图:


至此该爬虫完结,当然程序还有优化的地方,但功能实现了是首先的。这里用到的技术有:

1.requests+BeautifulSoup根据节点爬取网页内容

2.列表和字典的使用

3.csv文件的写入操作
看着自己的爬虫爬取了期望的数据当然是最开心的啦,继续加油~

当当网畅销书排行爬虫(requests+BeautifulSoup)相关推荐

  1. Python爬虫 离线爬取当当网畅销书Top500的图书信息

    本实例还有另外的在线爬虫实现,有兴趣可点击在线爬取当当网畅销书Top500的图书信息 爬虫说明 1.使用requests和Lxml库爬取,(用BS4也很简单,这里是为了练习Xpath的语法) 2.爬虫 ...

  2. Python爬虫 在线爬取当当网畅销书Top500的图书信息

    本实例还有另外的离线爬虫实现,有兴趣可点击离线爬取当当网畅销书Top500的图书信息 爬虫说明 1.使用requests和Lxml库爬取,(用BS4也很简单,这里是为了练习Xpath的语法) 2.爬虫 ...

  3. 金融数据分析(三)当当网店铺商品爬虫——爬虫类书籍为例:requestsbs4

    案例(二)爬虫预热 项目一:当当网店商品爬虫--爬虫类书籍为例 此案例是运用bs4库find方法对相关内容进行抓取. -*- coding: utf-8 -*- import requests imp ...

  4. 如何爬取当当网畅销书排行榜信息? requests + pyquery

    ''' 爬取当当网的五星图书排行榜的信息 ''' Max_Page = 3 # 爬取前三页的排行榜信息 import requests from pyquery import PyQuery as p ...

  5. 当当网读书排行榜爬虫

    引言 课题背景 随着互联网的快速发展,网上购物逐渐成为一种广为人知的购物方式,并且深受人们的喜欢.读书可以增加一个人谈吐的质量和深度.读书,可以让你掌握知识,而知识就像呼吸 一样,吐纳之间,可以见人的 ...

  6. python 爬虫 requests+BeautifulSoup 爬取巨潮资讯公司概况代码实例

    第一次写一个算是比较完整的爬虫,自我感觉极差啊,代码low,效率差,也没有保存到本地文件或者数据库,强行使用了一波多线程导致数据顺序发生了变化... 贴在这里,引以为戒吧. # -*- coding: ...

  7. python微博爬虫(requests+BeautifulSoup+selenium)

    备注:本爬虫程序在北京时间2020-5-20依旧有效,如果无效了,可以在评论中反馈. 1.需求 输入:微博账号链接(如:广州公安 https://weibo.com/gzjd) 输出:该账号所有发表的 ...

  8. 利用Python爬虫requests+BeautifulSoup实现丁香营销师招聘爬取(源码)

    为什么80%的码农都做不了架构师?>>>    https://download.csdn.net/download/shiyan_31214/10807090 转载于:https: ...

  9. 爬虫之requests+BeautifulSoup详解

    简介 Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种 ...

最新文章

  1. kafka_2.11-0.10.2.1中的auto.offset.reset
  2. quartus II Warning 好的时序是设计出来的,不是约束出来的
  3. android使用okthtp
  4. select、poll、poll的比较(转)
  5. 预告 | CSIG图像图形学科前沿讲习班:图神经网络
  6. GitHub 最受欢迎的Top 20 JavaScript 项目
  7. 基于智能手机Android平台音乐播放器全程开发实战
  8. oracle 客户端 for mips,盒子里的世界: MIPS虚拟机(zt)
  9. Servlet JSP和Spring MVC初学指南 PDF
  10. ASP用正则验证邮箱地址手机号码电话号码格式
  11. Riot v4.0.0-alpha.10 发布,JavaScript 的 MVP 框架
  12. python批量处理text_【RhinoPython】Rhino如何批量替换text 和Dot
  13. 微信emoji表情json文档
  14. cubemx6.0配置touchgfx 正点原子触摸屏,touchgfx添加触摸驱动
  15. 数据优化——分库分表(三)中间件讲解
  16. ProxySQL 配置详解及读写分离(+GTID)等功能说明2 (完整篇)
  17. 算法 | 你知道算法为什么这么重要吗?
  18. [Hadoop in China 2011] 人人网:基于Hadoop的SNS统计和聚类推荐
  19. 大连北站到大连计算机学校体育馆,大连北站到圣亚海洋世界怎么走
  20. 什么是 HTTP cookie?

热门文章

  1. HTML JS小游戏 制作飞机大战
  2. 携自游家逐浪新能源汽车赛道的李一男不想被同代人抛下
  3. 基于K8S的DevOps应用方案
  4. 排查解决 - Linux无法访问百度(公网)?
  5. MYSQL数据库系统第4次实验 单表查询
  6. Docker Swarm 创建加密覆盖网络
  7. 中南大学信息与通信工程专业研究生入学考试计算机网络试题2001答案,中南大学信息与通信工程专业研究生入学考试计算机网络试题.doc...
  8. matlab 高斯随机场,条件随机场(Conditional random fields)
  9. 电脑控制android 电视,怎么用电脑控制电视 电视应用安装器使用教程
  10. gta5结局杀老崔我哭了_GTA5中隐藏的第五种结局,答案令人吃惊,小富成赢家!...