重难点:使用scrapy获取的数值是unicode类型,保存到json文件时需要特别注意处理一下,具体请参考链接:https://www.cnblogs.com/sanduzxcvbnm/p/10309401.html

稍加改造也能保存到csv文件中

网址:https://sobooks.net/

1.网站分析

该图书网站的网址或者是https://sobooks.net/,或者是https://sobooks.cc/,本文以前者为例

首先看到的截止到当前时间(2019-01-23)共有172页,点击第二页,会发现网址变成:https://sobooks.net/page/2,点击第三页网址变成https://sobooks.net/page/3,不难想象,若是网址是https://sobooks.net/page/1,出现的页面是否跟https://sobooks.net/一样呢,结果是一样的,然后访问手动输入地址https://sobooks.net/page/172访问,会发现直接到最后一页了,顺便统计一下,最后一页有6本图书,前171页每页有24本图书,合计图书有171*24+6=4110本

这样一来就可以使用循环的方式来遍历每页的图书了

2.进入到图书详情页面,比如:https://sobooks.net/books/11582.html,会发现页面提供的有百度云网盘和城通网盘的下载地址,不过有些图书页面只提供百度云网盘的地址,所以本文只获取百度云网盘的地址。

页面上提供的是一个跳转链接地址,经过分析发现百度云网盘在=号后面,可以先提取出href的值然后使用split('=')切割获取后者即可得到百度云网盘地址

另外还需要在当前页面输入验证码提交后才能获取到百度云网盘的提取码。通过查看源码可知:

采用post的方式将验证码(2018919)提交到当前页面进而获得百度云提取码

一般的做法是进入到图书详情页面后再使用post方式提交验证码到当前页面获取提取码,不过这两步可以合成一步操作,就是采用post提交数据的方式进入到图书详情页面,这样一来,既进入了图书详情页面,同时页面上直接显示的就有提取码。不过scrapy默认使用的get方式,所以需要修改scrapy的中的相关方法;

3.进入到图书详情页面后接下来就按照正常流程输出需要的字段信息,全部采用css的方式(浏览器调试工具:css选择器),同时辅助使用表达式。

4.最后把图书信息保存到json文件中

5.源码文件

settings.py

增加如下内容,其余保持不变

ITEM_PIPELINES = {
'sobooks.pipelines.JsonWithEncodingPipeline': 200,
}

items.py

import scrapy

class SobooksItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field() url = scrapy.Field() title = scrapy.Field()
classification = scrapy.Field()
author = scrapy.Field()
down_bd_url = scrapy.Field()
down_bd_code = scrapy.Field()
down_ct_url = scrapy.Field()

pipelines.py

import codecs
import json class JsonWithEncodingPipeline(object):
"""
命令行里输出的是unicode,但是保存到json文件中是中文
""" def __init__(self):
self.file = codecs.open('items.json', 'w', encoding='utf-8') def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
# print('图书%s保存成功' % (item['title'].encode('utf-8')))
self.file.write(line)
return item def close_spider(self, spider):
self.file.close()

sobook.py

# -*- coding: utf-8 -*-

import re
import scrapy
from sobooks.items import SobooksItem class SobookSpider(scrapy.Spider):
"""
爬虫思路梳理
开始时的想法是使用get方式进入到书籍详情页面,然后再使用post方式给本页发送验证码获得百度云网盘提取密码,这样操作步骤较为繁琐
倒不如直接使用post方式给本页发送验证码,从而将上面的两步合成一步
""" name = 'sobook'
allowed_domains = ['sobooks.net']
base_url = 'https://sobooks.net/page/' pages = list(range(1, 173)) def start_requests(self):
# 遍历循环图书索引页
for page in self.pages:
url = self.base_url + str(page)
# print('请求第%s页' % (page))
yield scrapy.Request(url=url, callback=self.parse) def parse(self, response):
# 使用css选择器
res = response.css('#cardslist div.card').extract()
for card in res:
# 获取图书详情页链接
pattern = re.compile('<h3>.*?<a href="(.*?)".*?>.*?</a>.*?</h3>', re.S)
url = re.findall(pattern, card) # print('Get Book URI %s' % (url[0]))
# 使用post方式提交验证码进入图书详情页面
yield scrapy.FormRequest(url=url[0], formdata={'e_secret_key': ''},
callback=self.detail_parse) def detail_parse(self, response): title = response.css('.article-title > a:nth-child(1)::text').extract_first()
classification = response.css('#mute-category > a:nth-child(2)::text').extract_first()
author = response.css('span.muted:nth-child(2) > a:nth-child(2)::text').extract_first()
# 若是需要城通网盘地址,参考百度云网盘地址写法(CSS选择器)
down_bd_url = response.css(
'.dltable > tbody:nth-child(1) > tr:nth-child(3) > td:nth-child(1) > a:nth-child(2)::attr(href)').extract_first().split(
'=')[1]
down_bd_code = response.css('.e-secret > strong:nth-child(1)::text').extract_first() item = SobooksItem()
item['title'] = title
item['classification'] = classification
item['author'] = author
item['down_bd_url'] = down_bd_url
item['down_bd_code'] = down_bd_code yield item

6.效果:

通过查看json文件,发现有4098本图书数据,跟之前计算的4110本差2本,这2本具体是啥懒得找了,就先这样吧

通过分析json文件中的地址,应该取的是百度云网盘的地址,但是部分地址是城通网盘的,通过搜索图书查看发现该图书并未提供百度云网盘地址,只提供城通网盘地址

源码下载地址:https://files.cnblogs.com/files/sanduzxcvbnm/sobooks.7z

使用Scrapy爬取图书网站信息的更多相关文章

  1. 爬虫系列2:Requests+Xpath 爬取租房网站信息

    Requests+Xpath 爬取租房网站信息 [抓取]:参考前文 爬虫系列1:https://www.cnblogs.com/yizhiamumu/p/9451093.html [分页]:参考前文 ...

  2. python之简单爬取一个网站信息

    requests库是一个简介且简单的处理HTTP请求的第三方库 get()是获取网页最常用的方式,其基本使用方式如下 使用requests库获取HTML页面并将其转换成字符串后,需要进一步解析HTML ...

  3. 爬虫框架之Scrapy——爬取某招聘信息网站

    案例1:爬取内容存储为一个文件 1.建立项目 C:\pythonStudy\ScrapyProject>scrapy startproject tenCent New Scrapy projec ...

  4. scrapy爬取某网站,模拟登陆过程中遇到的那些坑

    本节内容 在访问网站的时候,我们经常遇到有些页面必须用户登录才能访问.这个时候我们之前写的傻傻的爬虫就被ban在门外了.所以本节,我们给爬虫配置cookie,使得爬虫能保持用户已登录的状态,达到获得那 ...

  5. 爬虫系列3:Requests+Xpath 爬取租房网站信息并保存本地

    数据保存本地 [抓取]:参考前文 爬虫系列1:https://www.cnblogs.com/yizhiamumu/p/9451093.html [分页]:参考前文 爬虫系列2:https://www ...

  6. scrapy 爬取天猫商品信息

    spider # -*- coding: utf-8 -*- from urllib.parse import urlencode import requests import scrapy impo ...

  7. python之scrapy爬取jingdong招聘信息到mysql数据库

    1.创建工程 scrapy startproject jd 2.创建项目 scrapy genspider jingdong 3.安装pymysql pip install pymysql 4.set ...

  8. scrapy爬取豆瓣电影信息

    最近在学python,对python爬虫框架十分着迷,因此在网上看了许多大佬们的代码,经过反复测试修改,终于大功告成! 原文地址是:https://blog.csdn.net/ljm_9615/art ...

  9. Python爬虫学习之使用beautifulsoup爬取招聘网站信息

    菜鸟一只,也是在尝试并学习和摸索爬虫相关知识. 1.首先分析要爬取页面结构.可以看到一列搜索的结果,现在需要得到每一个链接,然后才能爬取对应页面. 关键代码思路如下: html = getHtml(& ...

随机推荐

  1. 浅析Linux字符设备驱动程序内核机制

    前段时间在学习linux设备驱动的时候,看了陈学松著的<深入Linux设备驱动程序内核机制>一书. 说实话.这是一本非常好的书,作者不但给出了在设备驱动程序开发过程中的所须要的知识点(如对 ...

  2. 一次次迭代 百度语音生成 api 字幕 语音的同步性 关键

    发音字符 数一样 D:\myv\semHAND9myuid1523961381.avi 0.7053863117786668 --------------- 深圳市雅超服饰有限公司是一家专业设计制作高 ...

  3. jquery操作删除元素

    通过 jQuery,可以很容易地删除已有的 HTML 元素. 删除元素/内容 如需删除元素和内容,一般可使用以下两个 jQuery 方法: remove() - 删除被选元素(及其子元素) empty ...

  4. bzoj 3993 星际战争

    题目大意: X军团和Y军团正在激烈地作战  在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai 当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机 ...

  5. P3469 [POI2008]BLO-Blockade tarjan

    好久没发博客了啊!自我反省1s...今天再捡起来. 这个题是一道有一点特殊的tarjan,用tarjan维护子树大小,然后判断是否有边多次连接,(就是非树边),然后就进行乘法计算就行了. 具体在代码里 ...

  6. Applications(模拟)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3705 题意:主要是分值计算要注意以下几点: (1) 在MOJ上解出的题,如 ...

  7. [jzoj NOIP2018模拟10.23]

    丢分主要是下面几个方面: 1.T2代码交错了,有个特判没写丢了10分 2.T1线段树加等差数列写错了(其实二维差分就可以,但我当时不会) 3.T3思考再三还是为了10分写上了主席树,还是写错了 总体评 ...

  8. JavaScript中相等==和严格相等===的区别

    在JavaScipt中==(相等)和===(严格相等,strick equality 也有译作“恒等”.“全等”)用于比较两个值是否相等,两个运算符允许任意类型的操作数.如果操作数相等则返回true, ...

  9. Golang 入门 : goroutine(协程)

    在操作系统中,执行体是个抽象的概念.与之对应的实体有进程.线程以及协程(coroutine).协程也叫轻量级的线程,与传统的进程和线程相比,协程的最大特点是 "轻"!可以轻松创建上 ...

  10. MVC系列学习(三)-EF的延迟加载

    1.什么叫延迟加载 字面上可以理解为,一个动作本该立即执行的动作,没有立即执行 2.从代码上理解 static void Main(string[] args) { //执行该语句的时候,查看sql监 ...