python爬虫学习之路,为老婆爬下整站模板-第二章
第一阶段为初步阶段,只是为了了解或是花很少的时候解决当时的问题,想要完美是非常困难的,一步一步来吧
第二阶段为进阶阶段
第一阶段的问题做了些总结
- 断电后程序怎么继续执行
- 爬取一个页面大概要10秒左右,慢
针对这些问题做了些方案
- 每爬一个页面保存一个状态,知道那些读取完,那些没有
- 采取多线程加快进度
做一步学习一步,现在在网站上看到
Scrapy的强大,决定试试。
首先分析需求,现在只需要这四个板块的下载地址
image这是最基础的爬页面的scrapy框架,response.body就是取得返回html代码
image下面看看我们需要爬取的数据
这里有个小技巧,直接在需要采取的数据上右键,然后点检查
image然后在出来的firebug的要采集的数据上右键,复制xPath
image会看到(/html/body/div[3]/div[4]/div[4]/p[1]/b)这样的数据,多对比几个,如果都是一样的,就可以采取这种方式直接取得我们想要的数据,不在需要用正则去匹配。
在这里我在chrome里面复制的第一层div是第三个,但不知道怎么找不到,换成2才找到,难道是从0开始?但后面二个又不需要换了,真是奇了怪了。可能是有一个是js后来生成的吧,暂时先解决问题,后面在来研究
image这里有一个非常大的坑,就是编码问题,新手一般都会遇到这问题,虽然就一句代码,但不搞明白的话还是要走比较多的弯路,我首先是用chardet.detect(html)查看了编码,是gb2312的,先解码,在转成utf-8格式的,这样保存为文件里面就没问题了。
就这一句话就完成了,还是没有经验啊,呵呵
image在shell里面输出这样的是没问题的,保存到文件就是中文的
image这是采取到的数据保存的文件,中文是没问题的
image现在一个页面的基础爬取是没问题了,但这又遇到个问题,比如读取下一页连接,在爬取,在读取下一页,这虽然能写出来,但多进程又有问题,感觉scrapy的多进程不好控制。
我的想法是一个主进程,专门读取主页面的列表,把列表存入数据库里面,然后开启10个进程,来根据数据库里面数据的状态来执行任务
当然我这想法是在我不需要大面积爬取的情况下,如果有些需求需要大面积的爬取数据,用scrapy还是很不错的,我这里决定直接用request就行了,往scrapy这里转了一圈,最重要的是知道了用xpath能解决非常多的匹配问题。或许是自己对scrapy的认识深度还不够
不过能够解决需求就行了。
于是乎我又回到了urllib,所有说程序猿没事还是要多学习一些库啊,多看些文档,这些是能改善工作效率的。
首先编码的是list列表的读取
image这是一个读取列表页面的基本单元,运行之后数据库里会有这些数据
image同时在开始这个进程的时候,会读取数据库里面保存的已经完成到那一页的数据
image每完成个循环会写入一条到数据库,然后倒序查找到就行,如果查找不到就代表从第一页开始
image image这算是解决了程序异常结束之后继续执行的问题。
然后是多进程取得下载地址了,上面四个进程是四种类型的列表读取,并下载图片,下面是10个读取下载地址的进程。
image这是读取下载地址的方法
首先是查看有那一条数据状态为0的,然后更改状态为1,开始爬取下载地址,写入数据库,并更改状态为2
image这里有点麻烦的是百度网盘地址的读取,每个页面位置不一样,开始还好,后来就出问题了,这里加上了re匹配,抛出异常就为空吧,比较新的模板一般都有,以前的没有。
image这是数据库的结构
image这是运行状态,速度还可以,内存,cpu这块都还好,主要是网络瓶颈,一张图片大概100k左右吧。几万多张图
还有写入这块也有点慢。毕竟是张sd卡。当时写入系统的时候只有6M的速度
image image编码过程中遇到的问题
UnicodeDecodeError: 'gb2312' codec can't decode byte 0x8a in position 19746: illegal multibyte sequence
网页如果是采用的gb2312编码的话,采集下来需要先decode('gb2312'),这个问题是因为遇到了bg2312不认识的字了,这里换成gbk就行了,如果更高级的换成gb18030也行。