Python3 爬虫爬取中国图书网(淘书团) 记录

Posted InsistPy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3 爬虫爬取中国图书网(淘书团) 记录相关的知识,希望对你有一定的参考价值。

本人为一名刚开始学Python爬虫的小白,开贴仅为记录下自己的学习历程,方便做review

 

要爬取链接:http://tuan.bookschina.com/

要爬取内容: 图书名称, 图书价格, 以及对应预览图的link

本文用到py packages: requests, BeautifulSoup, json, cvs

打开中国图书网团购页面时,发现网站的信息是动态加载的:

Anyways,先不考虑加载更多页的图书信息,我们从尝试着抓取第一页的图书信息开始:

本次爬虫所用的浏览器为chrome

所以我们打开浏览器的开发者模式F12,可以看到页面加载的相应信息

为了实现模拟浏览器登录功能,我们需要查看header的信息:

完成对应的代码:

header = {
    \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36\',
    \'Host\': \'tuan.bookschina.com\',
    \'Referer\': \'http://tuan.bookschina.com/\',
    \'Accept\': \'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\',
    \'Accept-Encoding\': \'gzip, deflate\',
    \'Accept-Language\': \'zh-CN,zh;q=0.9\'
}

 

接下来我们需要做的就是分析整个中国图书网的DOM,去查看我们需要的信息,都封装在哪些tags里面

经过地毯式搜索。。。。我们发现我们所需要的信息,都封装在 <ul id=\'taoList".....>的子节点li里面

 

 

 所以,我们打算采取BeautifulSoup的解析抓取功能,来实现拿到li内的我们需要的信息

对应的代码:

url = \'http://tuan.bookschina.com/\'
response = requests.get(url, headers = header) #模仿浏览器登录
response.encoding = \'utf-8\'
soup = BeautifulSoup(response.text,\'html.parser\')
for item in soup.select(\'div .taoListInner ul li\'):
    print(item.select(\'h2\')[0].text) #返回对象为数组
    print(item.select(\'.salePrice\')[0].text)
    print(item.select(\'img\')[0].get(\'src\')) #get方法用来取得tab内部的属性值

 

首先我们需要调用requests的get方法,拿到响应的response,然后通过BS进行解析,我们会发现,在class 名为 taoListInner的div标签中,封装了我们想要的ul下的li

查看了beautifulsoup的文档,对比了find_all 和select,决定调用select方法拿到对应的标签,然后拿到对应h2标签下的书名; salePrice class下的价格; 以及img标签

内src的预览图link。这样就可以打印出我们想要的第一页所显示的书籍的信息了。

 

但是问题就出来了。。。如果我们想拿后续页面的更多书籍信息,该怎么办呢,因为bs的select方法是只能解析静态的Dom的

所以我们怀疑,后续的图书数据是通过Ajax 或者 JS 加载的

我们来到开发者模式的XHR下面,我们会发现,每当我们下拉滚动条,刷新图书信息的时候,会跟随者刷新出一个GroupList?.....的链接

我们打开他

 

惊喜的发现在Preview里,封装了我们需要的数据,并且是以Json形式予以保存的,这样变能让我们方便的拿到动态生成的图书数据了。

 

 

所以我们要拿到这个Json数据,首先需要去拿他的Request URL

当前的URL为:http://tuan.bookschina.com/Home/GroupList?Type=0&Category=0&Price=0&Order=11&Page=2&Tyjson=true

我们会发现一个规律,每当有新的书籍信息刷新一次的时候,生成的GroupList?...URL中的Page=?也会跟随递增

所以问题迎刃而解了。。。。我们只需要去通过遍历URL并拿到返回的JSON进行解析,便可以拿到我们想要的全部数据了

也验证了一个说法,许多动态加载的网站,都会把Json数据封装作为response,这样就给我们的爬虫找到一条捷径

 

url = \'http://tuan.bookschina.com/Home/GroupList?Type=0&Category=0&Price=0&Order=11&Page=2&Tyjson=true\'
response = requests.get(url)
result = json.loads(response.text)
bookinfo = {}
for data in result[\'Data\']:
    bookinfo[\'bookName\'] = data[\'book_name\']
    bookinfo[\'price\'] = data[\'group_price\']
    bookinfo[\'iconLink\'] = data[\'group_image\']
print(url)

 

这里用里调用了loads()方法,把返回的json数据转换为python的字典,方便拿数据

拿到数据后我们决定把数据存入磁盘,生成cvs的excel文件,相关的写入文件方法,请查阅python3官方文档。

方便做进一步的数据分析。

 

所以,本次爬虫小实验全部代码如下:

import requests
from bs4 import BeautifulSoup
import json
import csv

def parse_one_page():
    header = {
        \'User-Agent\': \'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36\',
        \'Host\': \'tuan.bookschina.com\',
        \'Referer\': \'http://tuan.bookschina.com/\',
        \'Accept\': \'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\',
        \'Accept-Encoding\': \'gzip, deflate\',
        \'Accept-Language\': \'zh-CN,zh;q=0.9\'
    }
    url = \'http://tuan.bookschina.com/\'
    response = requests.get(url, headers = header) #模仿浏览器登录
    response.encoding = \'utf-8\'
    soup = BeautifulSoup(response.text,\'html.parser\')
    for item in soup.select(\'div .taoListInner ul li\'):
        print(item.select(\'h2\')[0].text) #返回对象为数组
        print(item.select(\'.salePrice\')[0].text)
        print(item.select(\'img\')[0].get(\'src\')) #get方法用来取得tab内部的属性值


def dynamtic_scraping_data(page, headers, fileName):
    for i in range(page):
        url = \'http://tuan.bookschina.com/Home/GroupList?Type=0&Category=0&Price=0&Order=11&Page=\' + str(
            i) + \'&Tyjson=true\'
        response = requests.get(url)
        result = json.loads(response.text)
        bookinfo = {}
        for data in result[\'Data\']:
            bookinfo[\'bookName\'] = data[\'book_name\']
            bookinfo[\'price\'] = data[\'group_price\']
            bookinfo[\'iconLink\'] = data[\'group_image\']
            write_csv_rows(fileName,headers,bookinfo)
        print(url)

def write_csv_headers(path, headers):
    with open(path, \'a\', encoding=\'gb18030\', newline=\'\') as f:
        f_csv = csv.DictWriter(f, headers)
        f_csv.writeheader()


def write_csv_rows(path, headers, rows):
    with open(path, \'a\', encoding=\'gb18030\', newline=\'\') as f:
        f_csv = csv.DictWriter(f, headers)
         # 如果写入数据为字典,则写入一行,否则写入多行
        if type(rows) == type({}):
            f_csv.writerow(rows)
        else:
            f_csv.writerows(rows)
def main(page):
    # parse_one_page() #Tip: beautifulSoup test
    csv_filename = "bookInfo.csv"
    headers = [\'bookName\', \'price\', \'iconLink\']
    write_csv_headers(csv_filename,headers)
    dynamtic_scraping_data(page, headers, csv_filename)

if __name__ == \'__main__\':
    main(20) #input page num to start

 

以上是关于Python3 爬虫爬取中国图书网(淘书团) 记录的主要内容,如果未能解决你的问题,请参考以下文章

python&MongoDB爬取图书馆借阅记录(没有验证码)

Python3爬虫用Python实现发送天气预报邮件

爬虫实战利用scrapy框架爬取豆瓣图书信息

Python项目之我的第一个爬虫----爬取豆瓣图书网,统计图书数量

Python爬虫入门 | 4 爬取豆瓣TOP250图书信息

爬虫之爬取豆瓣图书的评论