日期:2020.02.09

博客期:148

星期日

  按照要求,我来制作 Python 对外爬取类的固定部分的封装,以后在用 Python 做爬取的时候,可以直接使用此类并定义一个新函数来处理CSS选择部分的动态选择。

  好了,先说一下设计初衷!我在之前两次的爬取任务中发现我用到的爬取仅仅就是 requests 爬取和 selenium 爬取,而且呢~这两部分的爬取都是按照一定的步骤来做的,第一步,网页加载;第二步,获取 HTML 内容;第三步,使用 CSS 选择器进行筛选;第四步,处理数据打包保存到文件。所以我就先把除了第三步以外的其余部分封装起来了(第三步 CSS 选择部分实在是太灵活了,封装的话要满足灵活性工作量太大,相当于我第一次做的那个连接数据库的Jar包,挺失败的【不过,代码到可以用】)。打包保存文件的部分可以使用 StringWriter (之前也说过了),也可以直接使用 基础 Bean 类的 toFile 方法,这里就直接封装 Bean 类了!

  先说目录结构,如下图。分为三个 py 文件,分别对应的是 Bean 、WebDataConnector、WebSelConnector。

Python 爬取的类封装【将来可能会改造,持续更新...】(2020年寒假小目标09)-LMLPHP

  Bean 类,这是对之前的基础 Bean 类的封装,内部保存了基础类在爬取过程中的实际用到的各种方法。

  WebDataConnector 类,这是 requests 的爬取方法的前两步的封装,具体实现需要自己定义一个方法。

  WebSelConnector 类,这是 selenium 的爬取方法的前两步的封装,具体实现需要自己定义一个方法。

  【代码仅供参考】

 import codecs

 class Bean:
group = {} def __init__(self):
pass # 重新初始化为实例化阶段
def __reset__(self):
self.group.clear() # 转为字符串类型
def __toString__(self):
num = self.group.__len__()
str_ret = ""
for i in range(0,num):
poi = str(list(dict(self.group).values())[i])
str_ret = str_ret + poi
if i != num - 1:
str_ret = str_ret + "\t"
return str_ret # 转为字符串类型 (带)
def __toStrS__(self,fgf):
num = self.group.__len__()
str_ret = ""
for i in range(0, num):
poi = str(list(dict(self.group).values())[i])
str_ret = str_ret + poi
if i == num - 1:
str_ret = str_ret + str(fgf)
return str_ret # 以追加形式追加到数据文件
def __toFile__(self,filepath):
f = codecs.open(filepath, "a+", 'utf-8')
f.write(self.__toString__() + "\n")
f.close()

Bean.py

 from urllib import request

 import parsel

 class WebDataConnector:
# 网页地址
web_url = ""
# 固定 header 内容
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36'
} # 初始化
def __init__(self,weburl):
self.__reset__(weburl) # 初始化为 最初状态
def __reset__(self,url):
self.web_url = url # 获取网页 HTML 内容
def __getHTML__(self):
req = request.Request(url=self.web_url, headers=self.headers)
r = request.urlopen(req).read().decode()
return r # 获取 CSS选择器的开始工具
def getNercol(self):
index_html = self.__getHTML__()
index_sel = parsel.Selector(index_html)
return index_sel

WebDataConnector.py

 import time

 import parsel
from selenium import webdriver # Selenium 爬取工具
class WebSelConnector:
# 启动器
run_tag = "" # 初始化
def __init__(self):
run_tag = webdriver.Firefox() # 把 页面 切到 url 对应网页
def __pageToURL__(self,url):
self.run_tag.get(str(url)) # 人工设置 线程停滞秒数
def __timeStop__(self,s):
time.sleep(s) # 获取 url 的内部 HTML 代码
def __getHTML__(self):
a = self.run_tag.page_source
return a # 定义释放方法
def __close__(self):
self.run_tag.quit() # 获取 CSS选择器的开始工具
def getNercol(self):
index_html = self.__getHTML__()
index_sel = parsel.Selector(index_html)
return index_sel

WebSelConnector.py

  【附加可作为基本类的过去用到的类】(以往博客的网页的代码将会被删除)

 import codecs

 # [ 封装一行文件写入的方法 ]
class StringWriter:
# 文件 路径
filePath = "" # 初始化
def __init__(self, str):
self.filePath = str
pass # 将 文件 清空
def makeFileNull(self):
f = codecs.open(self.filePath, "w+", 'utf-8')
f.write("")
f.close() # 在 文件 后 追加 一行 字符串 数据
def write(self, stri):
f = codecs.open(self.filePath, "a+", 'utf-8')
f.write(stri + "\n")
f.close()

StringWriter.py

 # [ 对字符串的特殊处理方法-集合 ]

 class StrSpecialDealer:
# 取得 当前 标签内的 文本
@staticmethod
def getReaction(stri):
strs = StrSpecialDealer.simpleDeal(str(stri))
strs = strs[strs.find('>')+1:strs.rfind('<')]
return strs # 去除 基本的 分隔符
@staticmethod
def simpleDeal(stri):
strs = str(stri).replace(" ", "")
strs = strs.replace("\t", "")
strs = strs.replace("\r", "")
strs = strs.replace("\n", "")
return strs # 删除 所有 标签 标记
@staticmethod
def deleteRe(stri):
strs = str(stri)
st = strs.find('<')
while(st!=-1):
str_delete = strs[strs.find('<'):strs.find('>')+1]
strs = strs.replace(str_delete,"")
st = strs.find('<') return strs # 删除带有 日期 的句子
@staticmethod
def de_date(stri):
lines = str(stri).split("。")
strs = ""
num = lines.__len__()
for i in range(0,num):
st = str(lines[i])
if (st.__contains__("年") | st.__contains__("月")):
pass
else:
strs += st + "。"
strs = strs.replace("。。", "。")
return strs # 取得带有 日期 的句子之前的句子
@staticmethod
def ut_date(stri):
lines = str(stri).split("。")
strs = ""
num = lines.__len__()
for i in range(0, num):
st = str(lines[i])
if (st.__contains__("年")| st.__contains__("月")):
break
else:
strs += st + "。"
strs = strs.replace("。。","。")
return strs # 去除 文件中 [1] 类型的 标识
@staticmethod
def beat(stri,num):
strs = str(stri)
for i in range(0,num):
strs = strs.replace("["+str(i)+"]","") return strs # 去除 字符串内的指定标签 针对 <></> 型标签 (innerHTML不去除)
@staticmethod
def del_label(stri,label):
s = ""
label = str(label)
strs = str(stri).replace("</"+label+">","")
num = strs.find('<'+label)
while num != -1:
num_s = strs.find('>',num)
str_s = strs[num:num_s+1]
strs = strs.replace(str_s,"")
num = strs.find('<' + label)
return strs

StrSpecialDealer.py

  【更新内容】

    //------------------------------------------------------------[2020-02-09:更新]

    我发现了 Bean 类型需要一个顺序输出器,就是在程序里按照一个列表内元素的顺序输出,我太需要这个了!

    下面是在 Bean 类里添加的代码:

 # 转为字符串 按照顺序输出
def __toStrSS__(self,link):
link = list(link)
num = link.__len__()
strs = ""
for i in range(0,num):
strs = strs + str(self.group[link[i]])
if i != num - 1:
strs = strs + "\t"
return strs

(Add Into Bean.py)

05-21 12:18