- 基础环境的安装
1.1下载python
1.2安装pywin32使得可以在windows上使用cmdline执行命令脚本。
下载pywin32,找到对应版本 pywin32对应的网址,下载下来安装即可。
1.3安装pip
下载文件getpip,然后在该文件所在目录下执行cmd命令python get-pip.py
1.4安装scrapy
执行命令pip install Scrapy(如果你电脑没有安装C++ 14.0运行库,就会报错Microsoft Visual C++ 14.0 is required,可以去运行库下载visualcppbuildtools_full安装完成,就可以成功安装。) - 创建一个空项目
2.1使用 scrapy startproject projectName。
2.2进入项目中使用scrapy genspider 文件名 域名 使用模板创建一个scrapy空项目 - 使用日志logging
使用NullHandler进行日志记录,在顶级_init_.py文件中添加下面的代码
import logging
try: # python 2.7+
from logging import NullHandler
except ImportError:
class NullHandler(logging.Handler):
def emit(self, record):
pass
logging.getLogger(__name__).addHandler(NullHandler())
日志配置目前常用dictConfig json项配置,fileConfig ini文件项配置
相关的日志配置项可以参考配置
在代码中使用日志logger=logging.getLogger()
logger.debug(’%s’, ‘test’)
- 添加项目描述文档
4.1.README文件,最好是reStructured格式,或者别的文件,作用是介绍项目目的,软件安装源的url,致谢之类的
4.2.INSTALL文件,提供安装步骤,可以是README文件中的一个小节
4.3.LICENSE许可证
4.4.TODO列出开发计划,可以是README文件中的一个小节
4.5.CHANGELOG最近的一些变更,可以是README文件中的一个小节 - 测试
使用unittest进行测试,测试套件(TestSuite)进行批量测试。
通过继承unittest.TestCase来创建测试用例,如下示例
import unittest
from software_design.spiders.check_code import ParityCode
class ParityCodeTestCase(unittest.TestCase):
def setUp(self) -> None:
self._number_ = 0B10101011011001101100
def test_get_num_of_one(self):
ParityCode.get_num_of_one(self._number_)
def test_is_one_of_data_even(self):
num = ParityCode.is_one_of_data_even(self._number_)
print(num)
def test_verify_data(self):
num = ParityCode.verify_data(self._number_)
print("数据校验是否通过:" + str(num))
集成测试
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(ParityCodeTestCase))
# 执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
使用mock进行测试模拟
from unittest import mock
temple.mothed = mock.Mock(return_value=1)
add_and_multiply中有multiply方法,但是该方法没有完成
from unittest.mock import patch
@patch("function.multiply")
def test_add_and_multiply2(self, mock_multiply):
x = 3
y = 5
mock_multiply.return_value = 15
addition, multiple = function.add_and_multiply(x, y)
mock_multiply.assert_called_once_with(3, 5)
self.assertEqual(8, addition)
- 命名空间工具
dir(object)返回该对象暴露出来的属性列表
globals()返回全局的属性字典
locals()返回当前命名空间属性字典 - scrapy使用示例
# -*- coding: utf-8 -*-
import scrapy
from recruit.items import PositionItem, NewContext
class PositionSpider(scrapy.Spider):
name = 'Position'
allowed_domains = ['www.people.com.cn']
start_urls = ["http://www.people.com.cn/"]
def parse(self, response):
position_lists = response.xpath('//div[@class="box fl ml35 news_center"]')
for postion in position_lists:
position_title = position_lists.xpath('./ul[@class="list14 top"]/li/a/text()').extract()
position_link = position_lists.xpath('./ul[@class="list14 top"]/li/a/@href').extract()
index = 0;
for link in position_link:
item = PositionItem()
item["position_title"] = position_title[index]
index = index + 1
item["position_link"] = link
yield item
yield scrapy.Request(link, dont_filter=True, callback=self.next_parse)
def next_parse(self, response):
item_list = response.xpath('//*[@id="rwb_zw"]')
for item in item_list:
book = NewContext()
book['content'] = item.xpath('./p').extract()
yield book
- itme定义
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html
import scrapy
class PositionItem(scrapy.Item):
# 新闻标题
position_title = scrapy.Field()
# 新闻URL
position_link = scrapy.Field()
class NewContext(scrapy.Item):
content = scrapy.Field()
- pipelines文件编写,该文件是处理json数据
import json
class RecruitPipeline(object):
def open_spider(self, spider):
self.file = open("position.text", "w", encoding="utf-8")
def process_item(self, item, spider):
dict_item = dict(item)
json_str = json.dumps(dict_item, ensure_ascii=False) + "\n"
self.file.write(json_str)
return item
def close_spider(self, spider):
self.file.close()