爬当当各分类下的五星图书

@DC学院《Python爬虫:入门+进阶》

报名了DC学员的爬虫课程,断断续续学了五个礼拜,才看完第一章。尽管技术还很菜,但一些中央的东西可以爬取了,也想趁这一次作业,来品尝一下这段日子攻读的学识。

本次作业采取爬取的网站是当当网,一方面是因为传说相比较简单,另一方面也有比较多的图书数据,特别是五星图书,包含了各类领域最受欢迎的书籍信息,对于寻找有价值的书本、分析好书的有的情状有所一定的市值。

废话不多说,先上准备爬取的页面链接:
http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-all-0-0-1-1

切切实实的页面如下图:

当当网五星图书页面


自我想爬取的多少是各分类(小说、中小学教辅、教育学、成功/励志……)下边的五星图书消息(书名、评论数、作者、出版社、出版时间、五星评分次数、价格、电子书价格之类)。

为了抓各分类下的书籍音信,首先看望点击各分类的时候,链接是否暴发变化。经过测试,在不同的分类,链接都是不同等的,事实阐明不是JS加载。

于是,第一步就是要博取不同分类的页面链接,先以“小说”类目作为样例来测试一下,复制xpath信息并收获链接。

复制”小说”类目的xpath信息


得到的xpath如下:

//*[@id="sortRanking"]/div[2]/a

皇冠直营现金网开户, 
遵照固定的老路,尝试拿到类目标题和页面链接:

from lxml import etree
import requests

url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-all-0-0-1-1'
data = requests.get(url).text
s = etree.HTML(data)

title = s.xpath('//*[@id="sortRanking"]/div[2]/a/text()')
href = s.xpath('//*[@id="sortRanking"]/div[2]/a/@href')

print(title)
print(href)

胜利地得到了类目标称号和链接:

尝试得到各第一个类目的名称和链接


到此地基本能够领略,当当网的反爬确实不严加,我竟然还没有安装Headers的音信,竟然也得以爬取到想要的数量。但最后在全部的代码中,仍然把headers加上了,保险起见吧。

既是这样,其他的链接也得以由此这样的主意来收获,于是相比较了弹指间多少个类目标xpath,很容易察觉规律。获取具有的类目链接如下:

from lxml import etree
import requests

url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-all-0-0-1-1'
data = requests.get(url).text
s = etree.HTML(data)
items = s.xpath('//*[@id="sortRanking"]/div')

for item in items:
    book_url=item.xpath('./a/@href')
    item_name=item.xpath('./a/text()')

    if len(book_url)>0:  #避免抓回来的链接是空的情况
        href=book_url[0]
        item_title=item_name[0]
        print(item_title)
        print(href)

爬回去的局部的链接

接下去就是个别爬取每个分类下的书籍新闻,以“随笔”为例,其实翻页特别简单,给多少个相比如下:

http://bang.dangdang.com/books/fivestars/01.03.00.00.00.00-all-0-0-1-1
http://bang.dangdang.com/books/fivestars/01.03.00.00.00.00-all-0-0-1-2
http://bang.dangdang.com/books/fivestars/01.03.00.00.00.00-all-0-0-1-3
…………………………

翻页也卓殊简单,只可是有一点点坑的是,爬回去的链接在代码中,需要对其翻页,就需要把链接构造出来。对重回来的链接举办解析,发现唯有是中档有五个数字不相同。于是我把这个数据取出来,在连续中传进去,这样可以社团通用的链接。

对此翻页的数量,粗略地看了刹那间挨家挨户类目标最大页数,最多的是25页,当然也有有限25页的。

于是乎构造出各样类目下都有25个页面的链接:

from lxml import etree
import requests
import time

url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-all-0-0-1-1'
data = requests.get(url).text
s = etree.HTML(data)
items = s.xpath('//*[@id="sortRanking"]/div')

for item in items:
    book_url=item.xpath('./a/@href')
    item_name=item.xpath('./a/text()')

    if len(book_url)>0:
        href=book_url[0]
        item_title=item_name[0]
        a=href[41:46]
        print(item_title)

        for page in range(1,26):
            per_url= 'http://bang.dangdang.com/books/fivestars/{}.00.00.00.00-all-0-0-1-{}'.format(a,page)
            print(per_url)

布局的翻页链接-小说

协会的翻页链接-中小学教辅

接下去就是去抓取不同页面的消息,没有异步加载,所以直接用xpath定位就OK。当然中间有部分小地点需要专注的是,每本书所包含的新闻是不同等的,所以用xpath去得到的时候不自然能博取到,就会出错。

完整的代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from lxml import etree
import requests
import time

url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-all-0-0-1-1'

headers = {
            'Host': 'bang.dangdang.com',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
        }

data = requests.get(url,headers=headers).text
s = etree.HTML(data)

with open('dangdang.csv','w') as outputfile:
    items = s.xpath('//*[@id="sortRanking"]/div')

    for item in items:
        book_url=item.xpath('./a/@href')
        item_name=item.xpath('./a/text()')

        if len(book_url)>0:
            href=book_url[0]
            item_title=item_name[0]
            a=href[41:46]
            print(item_title)

            for page in range(1,26):

                per_url= 'http://bang.dangdang.com/books/fivestars/{}.00.00.00.00-all-0-0-1-{}'.format(a,page)
                data2=requests.get(per_url).text
                f=etree.HTML(data2)

                try:
                    file=f.xpath('//ul[@class="bang_list clearfix bang_list_mode"]/li')
                    print('正在打印{}第{}页…………'.format(item_title,page))
                    time.sleep(2)

                    for book in file:
                        title=book.xpath('./div[@class="name"]/a/@title')[0]
                        author=book.xpath('string(./div[@class="publisher_info"][1])')
                        pinglun=book.xpath('./div[@class="star"]/a/text()')[0].strip('条评论')
                        wuxing=book.xpath('./div[@class="biaosheng"]/span/text()')[0].strip('次')
                        price_now=book.xpath('./div[@class="price"]/p/span[1]/text()')[0]
                        price_before=book.xpath('./div[@class="price"]/p/span[2]/text()')[0]
                        price_sale=book.xpath('./div[@class="price"]/p/span[3]/text()')[0]

                        try:
                            date=book.xpath('./div[@class="publisher_info"]/span/text()')[0]
                        except:
                            date='出版时间不详'

                        try:
                            company=book.xpath('./div[@class="publisher_info"][2]/a/text()')[0]
                        except:
                            company='出版社不详'

                        try:
                            price_e=book.xpath('./div[@class="price"]/p[@class="price_e"]/span/text()')[0]
                        except:
                            price_e="没有电子书"

                        outputfile.write('{},{},{},{},{},{},{},{},{},{}'.format(title,author,date,company,pinglun,wuxing,price_now,price_before,price_sale,price_e))

                except:
                    pass

爬取的多寡如下:

爬取数据截图

爬取数据截图

一共10000多行数据,对应不同世界的10000多本高评分的图书,当然会有一对双重总结,比如小说和文艺,就有过多书是同时在这五个类目标。可是不管怎么说,都得到了数码。

当当网本身并未怎么反爬机制,所以爬取也相比顺利。唯一的小麻烦就是抓回去的链接继续翻页和中间有的图书中有的音信缺失的拍卖。当然,这些对于有些有点经历的同班来说都不是什么样事。

本次写爬虫,确实也是两遍相比较系统地尝试,在此以前也没爬过这么多的数目。自知技术来不够拿到完美作业和奖赏,不过分外满面红光能从中得到提高,大神们见笑了。

相关文章