自定义爬取指定数据
接下来我们通过自定义来抓取我们需要的数据,目标为抓取这个页面中,每个详情页内容的标题、标签、描述、图片的url、点击图片所跳转的url。


点击首页中的 project name > reo,跳转到脚本的编辑界面

获取所有详情页面的url
index_page(self, response) 函数为获取到 www.reeoo.com 页面所有信息之后的回调,我们需要在该函数中对 response 进行处理,提取出详情页的url。
通过查看源码,可以发现 class 为 thum 的 div 标签里,所包含的 a 标签的 href 值即为我们需要提取的数据,如下图

代码的实现
-
def index_page(self, response): -
for each in response.doc('div[class="thumb"]').items(): -
detail_url = each('a').attr.href -
print (detail_url) -
self.crawl(detail_url, callback=self.detail_page)
response.doc(‘div[class=”thumb”]’).items() 返回的是所有 class 为 thumb 的 div 标签,可以通过循环 for…in 进行遍历。
each(‘a’).attr.href 对于每个 div 标签,获取它的 a 标签的 href 属性。
可以将最终获取到的url打印,并传入 crawl 中进行下一步的抓取。
点击代码区域右上方的 save 按钮保存,并运行起来之后的结果如下图,中间的灰色区域为打印的结果

注意左侧区域下方的几个按钮,可以展示当前所爬取页面的一些信息,web 按钮可以查看当前页面,html 显示当前页面的源码,enable css selector helper 可以通过选中当前页面的元素自动生成对应的 css 选择器方便的插入到脚本代码中,不过并不是总有效,在我们的demo中就是无效的~


抓取详情页中指定的信息
接下来开始抓取详情页中的信息,任意选择一条当前的结果,点击运行,如选择第一个

实现 detail_page 函数,具体的代码实现:
-
def detail_page(self, response): -
header = response.doc('body > article > section > header') -
title = header('h1').text() -
tags = [] -
for each in header.items('a'): -
tags.append(each.text()) -
content = response.doc('div[id="post_content"]') -
description = content('blockquote > p').text() -
website_url = content('a').attr.href -
image_url_list = [] -
for each in content.items('img[data-src]'): -
image_url_list.append(each.attr('data-src')) -
return { -
"title": title, -
"tags": tags, -
"description": description, -
"image_url_list": image_url_list, -
"website_url": website_url, -
}
response.doc(‘body > article > section > header’) 参数和CSS的选择器类似,获取到 header 标签, .doc 函数返回的是一个 pyquery 对象。
header(‘h1’).text() 通过参数 h1 获取到标签,text() 函数获取到标签中的文本内容,通过查看源码可知道,我们所需的标题数据为 h1 的文本。
标签页包含在 header 中,a 的文本内容即为标签,因为标签有可能不为1,所以通过一个数组去存储遍历的结果 header.items(‘a’),具体html的源码如下图:

response.doc(‘div[id=”post_content”]’) 获取 id 值为 post_content 的 div 标签,并从中取得详情页的描述内容,有的页面这部分内容可能为空。
其余数据分析抓取的思路基本一致。
最终将需要的数据作为一个 dict 对象返回,即为最终的抓取结果
-
{ -
"title": title, -
"tags": tags, -
"description": description, -
"image_url_list": image_url_list, -
"website_url": website_url, -
}
保存之后直接点击左边区域的 run 按钮运行起来,结果如图,中间灰色区域为分析抓取到的结果。

在主页把任务重新跑起来,查看运行结果,可以看到我们需要的数据都抓取下来

将数据保存到本地的数据库
抓取到的数据默认存储到 resultdb 中,虽然很方便通过浏览器进行浏览和下载,但却不太适合进行大规模的数据存储。
所以最好的处理方式还是将数据保存在常用的数据库系统中,本例采用的数据库为 mongodb。
参数的配置
新建一个文件,命名为 config.json,放在 pyspider 文件目录下,以 JSON 格式存储配置信息。文件到时候作为 pyspider 配置命令的参数。
文件具体内容如下:
-
{ -
"taskdb": "mongodb+taskdb://127.0.0.1:27017/pyspider_taskdb", -
"projectdb": "mongodb+projectdb://127.0.0.1:27017/pyspider_projectdb", -
"resultdb": "mongodb+resultdb://127.0.0.1:27017/pyspider_resultdb", -
"message_queue": "redis://127.0.0.1:6379/db", -
"webui": { -
"port": 5001 -
} -
}
指定了数据库的地址,“webui” 指定网页的端口,这时候我们可以改成 5001 试试,不再用默认的 5000。
Ps. 在运行之前,你得保证打开本地的数据库 mongodb 和 redis,具体怎么玩自行google,反正这两个界面跑起来就对了~


通过设置参数的命令重新运行起来:
pyspider --config config.json
数据库存储的实现
通过重载 on_result(self, result): 函数,将结果保存到 mongodb 中,具体代码实现
-
import pymongo -
... -
def on_result(self, result): -
if not result: -
return -
client = pymongo.MongoClient(host='127.0.0.1', port=27017) -
db = client['pyspyspider_projectdb'] -
coll = db['website'] -
data = { -
'title': result['title'], -
'tags': result['tags'], -
'description': result['description'], -
'website_url': result['website_url'], -
'image_url_list': result['image_url_list'] -
} -
data_id = coll.insert(data) -
print (data_id)
on_result(self, result) 在每一步抓取中都会调用,但只在 detail_page 函数调用后参数中的 result 才会不为 None,所以需要在开始的地方加上判断。
db = client[‘pyspyspider_projectdb’] 中数据库的名字 pyspyspider_projectdb 为之前在 config.json 配置文件中的值。
coll = db[‘website’] 在数据库中创建了一张名为 website 的表。
data_id = coll.insert(data) 将数据以我们制定的模式存储到 mongodb 中。
(除了重载on_result方法外,也可以通过重载ResultWorker类来实行结果的处理,需要在配置文件中加上对应的参数。)
重新新建一个任务,将完整的代码拷进去,在主界面完成的跑一遍。
运行过程中可以看到 mongodb 中的打印不断有数据插入

运行完成后,浏览器查看结果,因为设置了数据库的存储,不再存储在默认的 resultdb 中,此时浏览器的result界面是没有数据的

通过命令行进入数据库查询数据:
-
use pyspyspider_projectdb -
db.website.find()
可看到存储到的数据
-
{ "_id" : ObjectId("5819e422e8e70103751f0f4c"), "image_url_list" : [ "http://media.reeoo.com/MING Labs.png!main" ], "website_url" : "https://minglabs.com/en", "tags" : [ "design company", "onepage", "showcase" ], "description" : "MING Labs is a UX design and development company with offices in Germany, China and Singapore. We craft digital products for all screens and platforms.", "title" : "MING Labs" } -
{ "_id" : ObjectId("581ad797e8e7010fa8ea85c1"), "tags" : [ "onepage" ], "title" : "SpaceTravellers", "website_url" : "https://www.totaltankstelle.de/spacetravellers/", "image_url_list" : [ "http://media.reeoo.com/SpaceTravellers.png!main" ], "description" : "Sie haben Treibstoff gesucht und viel mehr gefunden." } -
{ "_id" : ObjectId("581ad8ede8e70112e51bd4e1"), "website_url" : "http://aftershock.cc/", "title" : "Aftershock", "tags" : [ "onepage" ], "description" : "Evento de design para aqueles que estão tentando viver (ou quase) de arte. Chega mais! Dia 22-23 de outubro. Botafogo-RJ", "image_url_list" : [ "http://media.reeoo.com/Aftershock.png!main" ] } -
{ "_id" : ObjectId("581ad8ede8e70112e51bd4e3"), "website_url" : "http://www.proudandpunch.com.au/", "title" : "Proud & Punch", "tags" : [ "food", "ice cream", "onepage" ], "description" : "At Proud & Punch, we’re all about real flavours that pack a punch. We start with fresh ingredients and turn them into tasty treats with a whole lot of flair, right here in Australia. We don’t take shortcuts and have nothing to hide. We’re just proudly real, proudly delicious and proudly here to give you the feel-good treat you’ve been waiting for.", "image_url_list" : [ "http://media.reeoo.com/Proud & Punch.png!main" ] } -
{ "_id" : ObjectId("581ad8ede8e70112e51bd4e5"), "website_url" : "http://www.mobil1.com.sg/theendlessrace-game/", "title" : "The Endless Race", "tags" : [ "game" ], "description" : "", "image_url_list" : [ "http://media.reeoo.com/The Endless Race.png!main" ] } -
{ "_id" : ObjectId("581ad8eee8e70112e51bd4e7"), "website_url" : "http://www.maztri.com/en/", "title" : "Maztri", "tags" : [ "design agency", "showcase" ], "description" : "Maztri est une agence d’architecture intérieure et de design qui travaille sur la sensorialité des espaces et des objets qui nous entourent.", "image_url_list" : [ "http://media.reeoo.com/Maztri.png!main" ] } -
...
至此,我们便已将所抓取到的结果存储到了本地。
其他
本文所举例子只是最基本的使用方式,更复杂的,如通过参数的配置,让爬虫长期运行与服务器定期对数据进行更新,对根网页进行更深层次的处理,通过集群的方式来运行爬虫等。感兴趣的可自行去研究了。
另,这个框架是国人写的,附上官方文档的地址
完整的源码实现地址在这,直接拷贝粘贴到代码区域就能用,用的是python3。
本文介绍了如何使用pyspider自定义爬虫抓取指定网页的数据,包括标题、标签、描述和图片URL。详细讲述了如何从首页获取详情页URL,再到详情页抓取所需信息。数据抓取后,将其存储到本地的MongoDB数据库,通过配置`config.json`文件,并重载`on_result`函数实现数据保存。最后,文章提供了进一步学习和实践pyspider的可能性。

3088

被折叠的 条评论
为什么被折叠?



