51Testing软件测试论坛

标题: pyspider使用实例 [打印本页]

作者: 测试积点老人    时间: 2018-11-29 14:26
标题: pyspider使用实例
本帖最后由 测试积点老人 于 2018-11-29 14:30 编辑

创建项目:

[attach]119687[/attach]
创建后项目内容:

[attach]119688[/attach]

实例
操作步骤:
[attach]119689[/attach]

[attach]119690[/attach]

数据库内容如下:


        使用mongodb数据库:


[attach]119691[/attach]


代码如下:


  1. #!/usr/bin/env python
  2. # -*- encoding: utf-8 -*-
  3. # Created on 2018-06-14 17:11:18
  4. # Project: qiushi

  5. from pyspider.libs.base_handler import *
  6. import pymongo, requests
  7. from fake_useragent import UserAgent
  8. import time

  9. def get_proxy():
  10.     return requests.get('http://localhost:5010/get/').text
  11.     #由于代理池获取的免费代理,不稳定!因此后面的就不在使用代理,仅仅在这里把获取过程的封装函数放在这里!!
  12.    
  13. class Handler(BaseHandler):
  14.    
  15.     ua = UserAgent()
  16.     headers = {
  17.         'User-Agent': ua.random,
  18.         # 'Host':
  19.         # 'Referer':
  20.     }
  21.    
  22.     # 创建client和db
  23.     client = pymongo.MongoClient('localhost')
  24.     db = client['qidian']
  25.    
  26.     # 对于整个爬虫项目的全局配置:所有的self.crawl()在请求的时候都会加载这个配置。
  27.     crawl_config = {
  28.         'headers': headers,
  29.         # 'proxy': get_proxy(),
  30.         'itag': 'v0'
  31.     }
  32.    
  33.     # 增量爬虫1:每天重新启动爬虫的时候,只爬取页面上更新的数据。(采用去重策略)
  34.     # 增量爬虫2:url没有变化,数据更新了。(不能采用去重,每天都要重新爬取)
  35.      # 项目启动首先进入的函数
  36.     # @every: 用于设置定时爬取任务:可以是minutes, 也可以设置为seconds。
  37.     @every(seconds=2 * 60)
  38.     def on_start(self):
  39.         # 初始爬取的url
  40.         self.crawl('https://www.qidian.com/all', callback=self.index_page,validate_cert=False)
  41.    

  42.     # age: 主要是对任务url进行去重/过滤(根据taskid),每一个url有唯一的一个标识taskid,age是一个以秒为单位的时间点,
  43.             #如果在这个时间范围内,遇到了相同的taskid,这个任务就会被丢弃。
  44.    

  45.     @config(age=60)
  46.     def index_page(self, response):
  47.         # response.doc返回一个pyquery对象
  48.         for each in response.doc('h4 > a').items():
  49.             #fetch_type='js', js_script="":如果是javascript代码,需要在self.crawl()加入该参数
  50.              self.crawl(each.attr.href, callback=self.detail_page, validate_cert=False)
  51.             
  52.         # 找到下一页
  53.         # next_page = response.doc('.lbf-pagination-item-list > li:nth-of-type(9) > a')
  54.         # self.crawl(next_page.attr.href, callback=self.index_page, validate_cert=False)
  55.    
  56.    
  57.     # age的默认值是-1,永远不过期。
  58.     @config(priority=2,age=60)
  59.     def detail_page(self, response):
  60.         # 从response中解析详情页的数据
  61.         name = response.doc('h1 > em').text()
  62.         author = response.doc('h1 a').text()
  63.         tag = response.doc('.tag').text()
  64.         info = response.doc('.intro').text()
  65.         
  66.         print(time.time())
  67.         
  68.         print(name)
  69.         print(author)
  70.         print(tag)
  71.         print(info)
  72.         return {
  73.             "time": str(time.time()),
  74.             "url": response.url,
  75.             "title": response.doc('title').text(),
  76.             "name":name,
  77.             "author":author,
  78.             "tag":tag,
  79.             "info":info,
  80.         }
  81.     # on_result是固定的函数,只要一个函数中有return,就会自动调用这个函数。
  82.     def on_result(self, data):
  83.         # 将detail_page函数返回的结果,保存至mongodb中
  84.         #print('接收到数据了.....',response['url'])
  85.         if data == None:
  86.             print('空')
  87.         else:
  88.             if self.db['q'].update_one({'name': data['name']}, {'$set': data}, True):
  89.                 print('数据保存成功')
  90.             else:
  91.                 print('数据保存失败')
复制代码









欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2