python 爬虫实例_Python 爬虫:Pyspider 实例(二)

本文详细介绍了如何使用Pyspider爬虫从电影下载网站ygdy8.com抓取所有欧美影片的下载链接。通过分析页面结构,编写爬虫程序,包括项目的初始化、页面遍历、数据提取和详细页面处理。最终实现从189个页面中获取电影名字和下载链接,并展示了如何在Pyspider中调试和运行爬虫项目。
摘要由CSDN通过智能技术生成

一次性付费进群,长期免费索取教程,没有付费教程。

进微信群回复公众号:微信群;QQ群:460500587

 教程列表  见微信公众号底部菜单 |   本文底部有推荐书籍 

1975d8329e07ff8a5ba3e9dfef9ec78c.png

微信公众号:计算机与网络安全

ID:Computer-network

编写一个完整的“纯粹的”Pyspider项目。选一个简单的项目,在电影下载网站爬取所有的欧美影片的下载地址。

1、项目分析

选择的电影下载网站是http://www.ygdy8.com。在浏览器中打开这个网站,在网页顶部使用鼠标单击欧美电影链接,如图1所示。

25ddee7b692af1f8cee14e461bdcdec0.png

图1  项目起始页

此时显示项目的起始页面为http://www.ygdy8.com/html/gndy/oumei/index.html,移动页面右侧的下拉条,查看页面底部。将鼠标移动到末页链接上,页面左下角将显示该链接的链接地址,如图2所示。

7f373f3095650c5ba28561e49f03c248.png

图2  项目末页

单击末页链接,进入末页页面。在页面底部将鼠标分别移动到各个链接上,以分析链接地址规则,如图3所示。

e5e5bbc586c10b9590327218e048f584.png

图3  分析链接地址

单击首页链接,与开始的页面http://www.ygdy8.com/html/gndy/oumei/index.html对比一下,两者完全相同,因此可以得出结论:这个项目需要爬取的链接为http://www.ygdy8.com/html/gndy/oumei/list_7_,加上[1.html, 189.html]。

在这些链接中需要得到两个数据,一个是电影的名字,一个是电影的链接。以最后一页的最后一个电影为例,将鼠标移动到最后一个电影的链接上,如图4所示。

29d00bf9d01fb6de166716a54aba76ea.png

图4  有效数据

项目的基本流程就是这样了,首先分析这189个页面,获取电影名字和电影链接,然后到链接页面获取电影的具体信息,比如放映时间、电影主演、下载地址等。

2、爬虫编写

在浏览器中打开Pyspider的webui(Pyspider控制台),单击Create按钮创建新项目。项目名为oumeiMovie,起始地址可以为空。单击Create按钮进入调试界面。

与上一个项目youkuHotTvList不同,这个项目需要爬去的页面比较多,目前是189页。在函数on_start回调index_page函数之前,必须先把所有需要爬的页面统计出来,因此在Handler类中添加一个构造函数,用来统计爬取的页面,再到on_start函数中,循环回调index_page函数处理这些页面,如图5所示。

ef68e44b13b921d4b25bb0f01fc35b14.png

图5  统计爬取页数

单击页面右侧代码编辑区右上角的save按钮后,单击页面左侧预览区右上角的Run按钮,执行结果如图6所示。

f2032819184d3cec8bbf41d6ea1a8058.png

图6  爬虫入口页面

显示有189页,与设计结果相符。url显示也是正常的。继续下一步,修改index_page函数。在这个函数中获取电影名称和电影下载的页面,然后通过电影下载页面链接回调detail_page函数获取最终的数据。打开页面源码,找到离有效数据最近的标签。这里离有效数据最近,也最容易识别的是Table标签,如图7所示。

b177a9ad9ace63c1dd16ccf31b69ccd5.png

图7  页面源码中定位有效数据标签

查找显示有25个相同的标签,这与页面显示是相符合的。根据查找得到的标签,修改index_page函数,如图8所示。

59b3bb63bf48e3c53c054ff72a85a9b5.png

图8  修改index_page函数

在index_page函数中并没有使用pyquery定位过滤,而是使用的bs4定位过滤。这是因为所需数据movieName存在于标签内,而在标签附近有一个与它属性完全相同的标签。如果使用pyquery来定位,要么用next方法来分辨,要么添加条件判断来分辨,不如bs4方便。现在来测试一下结果,单击Run按钮,选择页面预览栏下面任意一个链接,单击右侧的三角运行按钮,如图9所示。

798023b7d4089b24e68ef29339828dea.png

图9  获取页面下载页

从中可以看出,index_page函数解析出了25个结果。这与页面源码中搜索得到的结果是相符的。爬虫程序的下一步是使用回调detail_page函数,用于处理得到的下载页面链接地址。

注意,这个回调函数self.crawl(url, callback=self.detail_page, save={‘movieName’:movieName})与Pyspider默认的回调函数略有不同,这里多出了一个save的字典参数。这个参数很重要,有时候index_page函数需要将一些参数传递给detail_page函数(在这个爬虫中也可以不要,因为在下一步detail_page函数中也可以解析得到movieName,这里只是做演示)。但两个函数都是回调函数,是无法直接传递参数的。使用全局变量传递参数也不行,因为Pyspider采用的是广度优先算法(深度优先算法倒是可以用全局变量传参),全局变量只能传递最后一个页面的参数。因此这里不得不借助其他的参数来传递值。再来仔细看一下回调的函数detail_page,它定义的是def detail_page(self, response),只带有一个参数response。这就意味着如果index_page函数需要传参给detail_page函数,就只能借助response这个参数来传递了。response这个参数是怎么样的呢?它来自于Pyspider的安装目录下的lib/response.py,到该目录下执行命令:

vi response.py

执行结果如图10所示。

21a1ba09cd91f30d0954c042292a1848.png

图10  使用save参数传值

这里save定义的是None,其实可以将save定义为任何类型。也许会有多个值需要传递,还是将save定义为字典更方便。

回到爬虫程序,继续下一步。利用save传递参数,修改detail_page函数,获取最终需要的数据。任意挑选一个电影下载页面的链接在浏览器中打开。

查看该页面的源代码,找到这些有效数据的位置,如图11所示。

1b24ccfe97b3370a2e3c07e6d25e294f.png

图11  源码中有效数据

电影下载链接的定位和过滤不难,不管是用bs4还是pyquery都很简单,但电影信息就有点麻烦了。因为源代码中电影信息内使用了大量的
标签。众所周知,
标签是由
…标签组“进化”而来的,但bs4和pyquery都只能从闭合的标签组中过滤出有效数据(至少目前是如此)。所以在这里要过滤出电影的信息,就要先把
标签过滤出去,然后在剩下的数据中使用re模块来过滤有效信息。因此,修改爬虫中函数detail_page,如图12所示。

aa9eb0685330e26e2ad1c1bcb797b5c5.png

图12  过滤电影有效信息

先单击爬虫页面右侧代码编辑区右上角的Save按钮保存爬虫代码,再单击页面左侧页面预览区右上角的Run按钮,在左侧页面预览区下部过滤得出最终所需的有效数据。

3、爬虫运行、调试

现在这个爬虫基本上编辑完毕了,可以试运行一下。单击页面左上角的pyspider链接,或者在地址栏中输入Pypider爬虫IP:5000,进入Pyspider主界面(控制台)。

每个爬虫都被分为了7列,分别为Group、Project Name、Status、rate/burst、avg time、Progress、Actions。

Group:组名是可以修改的,直接在组名上单击进行修改。如果需要对爬虫进行标记,可以通过修改组名来完成。

组名改为delete后如果状态为stop状态,24小时后项目会被系统删除。

Project Name:项目名只能在开始创建时确定,不可修改。

Status:显示的是当前项目的运行状态。每个项目的运行状态都是单独设置的。直接在每个项目的运行状态上单击进行修改。运行分为五个状态:TODO、STOP、CHECKING、DEBUG、RUNNING。

各状态说明:TODO是新建项目后的默认状态,不会运行项目;STOP状态是停止状态,也不会运行;CHECKING是修改项目代码后自动变的状态;DEBUG是调试模式,遇到错误信息会停止继续运行;RUNNING是运行状态,遇到错误会自动尝试,如果还是错误会跳过错误的任务继续运行。

Rate/Burst:这一列是速度控制。Rate是每秒爬取的页面数,Burst是并发数。默认情况下是1/3,意思是每秒3个并发,每个并发爬一个页面。这一项是可以调整的,如果被爬的网站没做什么限制,可以把这个数稍微调高一点。

Avg Time:平均运行时间。

Progress:爬虫进展统计。一个简单的运行状态统计。5m是五分钟内任务执行情况,1h是一小时内运行任务统计,1d是一天内运行统计,all是所有的任务统计。

Actions:这一列包含了3个按钮,即Run、Active Tasks、Results。run按钮是项目初次运行需要点的按钮,这个功能会运行项目的on_start方法来生成入口任务。Active Tasks按钮显示最新任务列表,方便查看状态,查看错误。Results按钮查看项目爬取的结果。

目前爬虫刚编辑完成,所以该项目状态为TODO,单击TODO状态,在弹出的菜单中将状态修改为DEBUG(也可以选择RUNNING),如图13所示。

445af263aa7d5b73de755b500a8f90f3.png

图13  修改项目运行状态

默认的速度是每秒3次,这个速度太慢了。单击项目的Rate/Burst列,修改并发数和爬取页面的速度,暂时修改为3/10,如图14所示。

94872bf8b0ebe54f833da2f812a9776f.png

图14  爬虫速度控制

设置完毕后,单击项目右侧的Run按钮,开始运行爬虫。稍等几分钟后就会有结果出现了。单击项目右侧的Results按钮,如图15所示。

23993fbaf948c113197ee916472a03d7.png

图15  爬虫结果

在页面右上角选择保存的格式,可以保存为json、txt、csv三种格式(基本上是够用的)。回到Pyspider控制台,单击项目右侧的Active Tasks按钮,如图16所示。

b3b1e11cbdcebfd283394f83826c48a5.png

图16  爬虫Log

显示有2次错误。单击错误链接查看错误原因,一般都是因为bs4按照过滤条件没有获取到合适的结果造成的,按照提示修改爬虫代码。最终修改后的爬虫代码如下:

1 #!/usr/bin/env python

2 # -*- encoding: utf-8 -*-

3 # Created on 2017-12-15 14:03:00

4 # Project: oumeiMovie

5

6 from pyspider.libs.base_handler import *

7 from bs4 import BeautifulSoup

8 import re

9 import codecs

10

11

12 class Handler(BaseHandler):

13     crawl_config = {

14     }

15

16     def __init__(self):

17         self.urls = []

18         for page in range(1, 178 + 1):

19             url = 'http://www.ygdy8.com/html/gndy/oumei/list_7_' +str(page) + '.html'

20             self.urls.append(url)

21

22     @every(minutes=24 * 60)

23     def on_start(self):

24         for url in self.urls:

25             self.crawl(url, callback=self.index_page)

26

27     @config(age=10 * 24 * 60 * 60)

28     def index_page(self, response):

29         soup = BeautifulSoup(response.text, 'lxml')

30         try:

31             Tags = soup.find_all('table', attrs={'width':'100%','border':'0','cellspacing':'0','class':'tbspan','style':'margin-top:6px'})

32         except Exception as e:

33             pass

34         for tag in Tags:

35             try:

36                 movieName = tag.find_all('a')[-1].get_text()

37                 movieHref = tag.find_all('a')[-1].get('href')

38                 url = 'http://www.ygdy8.com' + movieHref

39             except Exception as e:

40                 pass

41             self.crawl(url, callback=self.detail_page, save={'movieName':movieName})

42

43

44     @config(priority=2)

45     def detail_page(self, response):

46         movieName = response.save.get('movieName')

47         html = re.sub('
{1,5}', '', response.text)

48         try:

49             dataStr = re.search(u'◎.*

50         except Exception as e:

51             pass

52         soup = BeautifulSoup(response.text, 'lxml')

53         try:

54             hrefTag = soup.find('td', attrs={'style':'WORD-WRAP: break-

word', 'bgcolor': '#fdfddf'})

55             href = hrefTag.find('a').get('href')

56         except Exception as e:

57             pass

58         dataList = dataStr.split(u'◎')

59         dataDic = {u'译名':'', u'片名':'' , u'年代':'',u'产地':'',u'类别':'',\

60                    u'语言':'' , u'字幕':'' , u'IMDb评分 ':'' , u'豆瓣评分':'' , u'文件格式':'' , u'downUrl    ': href,\

61                    u'视频尺寸':'' , u'文件大小':'' , u'片长':'' , u'导演':'' ,u'主演':'' , u'简介 ':'', u'movieName':movieName}

62         for key in dataDic.keys():

63             for st in dataList:

64                 if re.search(key, st):

65                     dataDic[key] = re.sub(key, '', st)

66                     break

67         return dataDic

在中文字符前加上u,意思是指字符编码为unicode。

解决方法起始很简单,只要在bs4搜索结果时加上except就可以了。好了,现在已经将爬虫代码修改完毕,保存后回到Pyspider控制台。单击oumeiMovie项目中的Run按钮,观察Active Tasks的结果,却发现Pyspider爬虫虽然从入口启动,但并没有真正地开始作业。这是因为Pyspider爬虫除了第一次运行时是用单击Run按钮启动的,之后爬虫的运行是由代码中的scheduler(调度器)控制的,如图17所示。

d5d07abe6a0cc0aa706b1d6fe500a14b.png

图17  Pyspider scheduler

从图17中可以看到,在Pyspider默认定义的三个函数的上一行中有一个以@开头的函数。这个是Python的装饰器。装饰器是Python的高阶函数这里不做解释。有兴趣的朋友可自行上网搜索学习。@every(minutes=24*60)在这里是作为调度器使用的,意思是on_start函数每天执行一次。@config(age=10*24*60*60)也是调度器,意思是当前request的有效期是10天,10天内遇到相同的请求将忽略。最后@config(priority=2)是优先级设置,数字越大就越先执行。没有特殊要求,一般不需要修改默认的设置。

4、删除项目

项目运行完毕,得到了想要的结果。保存好结果,这个项目就没什么用处了。下一步就是删除项目了。删除Pyspider项目的方法有两种。

方法一:官方推荐常规的删除方法是将需要删除的项目状态设置为STOP,然后把项目的Group修改为delete,如图18所示。

862a4b061b03ced01812eed087df2199.png

图18  删除项目常规方法

在24小时后,Pyspider的服务端就将该项目删除了。这是为了给性急的用户一个后悔的机会,如果认定不后悔,那就参考方法二。

方法二:Pyspider所有的文档都保存在启动Pyspider的目录下的data文件夹中,而所有的项目都保存在data文件夹下的project.db文档内,因此删除Pyspider项目,只需要在project.db文档中删除相应的记录就可以了。执行命令:

ls

cd data

ls

sqlite3 project.db

.tables

select name from projectdb;

delete from projectdb where name='test';

如果没有安装Sqlite3,则需要使用apt-get安装。

执行结果如图19所示。

5e11520232c09f8dfb50ed36c6df801a.png

图19  从文档中删除项目

回到Pyspider控制台页面,刷新一下,可以看到test项目已经被删除了,如图20所示。

5617ee4ae4f96a8bf6f2e9d714a5855d.png

图20  快速删除Pyspider项目

同理,如果需要修改项目的result、task,只需要用Sqlite3命令修改相应的数据库文件就可以了。

微信公众号:计算机与网络安全

ID:Computer-network

【推荐书籍】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值