前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计了一个简易的Python GUI界面

设计了一个简易的Python GUI界面

作者头像
luanhz
发布2020-03-31 17:15:58
2K0
发布2020-03-31 17:15:58
举报
文章被收录于专栏:小数志

我们都知道GUI界面设计不是python的强项,但作为万金油编程语言,python也并不是不支持GUI开发。

00 目标提出

设计一个支持多个招聘网站的检索,可以通过指定目标城市、检索职业和查询数量,个性化输出检索结果,尔后将结果显示在界面并保存于文档中。

01 基本思路

  • 界面的主体是检索功能,其实质是一个爬虫程序,根据指定的检索条件爬取相应的求职信息字段,而为了支持多个招聘网站的爬虫,实际上要每个平台都设计相应爬虫程序。为了体现python的面向对象,可以将这些爬虫程序写成一个求职爬虫类,以便后续import。
  • 界面框架设计,python当前有3种实现方式,分别是Tkinter、wxWidgets、PyQt5或Pyside2,三种方式各有利弊,但从直观便捷的角度看,PyQt5或Pyside2更具优势。这二者较为相似,本次设计中选用Pyside2。
  • 几个控件,在Pyside2的Designer模式,直接设计控件及布局,主要是选用了comBox作为实现平台、常用城市列表的下拉框实现,用lineEdit实现关键词的输入,用pushButton实现查询和清空的按钮功能,用spinBox指定查询数量,最后用plainTextEdit的只读模式呈现检索结果。
  • 检索结果的保存选用最简单的csv文件,保存至当前目录,并用“日期_平台_城市_职业_条数”命名以作区分。

02 核心代码

  • 求职爬虫类:主要是定义一个爬虫类,参数包括3个关键字:城市,职业和爬取页码(便于后续及时显示),尔后分别定义3个招聘平台的爬虫程序,不同的爬虫程序中根据传入的关键参数形成目标url,即可解析获得相应的招聘字段信息。
代码语言:javascript
复制
class JobCrawler:
    def __init__(self, city, jobName, page):
        self.city = city
        self.jobName = jobName
        self.page = page

    def get_jobs_51job(self):
        citys = {'北京': '010000', }
        try :
            cityID = citys[self.city]
        except:
            cityID = "000000"
        url = "https://search.51job.com/list/{},000000,0000,00,9,99,{},2,{}.html".format(cityID, self.jobName, str(self.page))
        response = requests.get(url, headers = HEADERS)
        html = etree.HTML(response.text)
        contents = html.xpath("//div[@class='dw_table']/div[@class='el']") 
        jobs = []
        for content in contents:
            try:
                # 逐字段解析
                jobs.append(job)
            except:
                pass
        return jobs   

    def get_jobs_zhilian(self):
        url = "https://fe-api.zhaopin.com/c/i/sou?"
        params = {"start":(self.page-1)*50, "cityId":self.city, "kt":3, "kw":self.jobName, "pageSize":50}
        response = requests.get(url = url, headers = HEADERS, params = params)
        dic_results = json.loads(response.text)
        results = dic_results['data']['results']
        jobs = []
        for result in results:
            try:
                #逐字段解析
                jobs.append(job)
            except:
                pass
        return jobs

    def get_jobs_liepin(self):
        citys = {'北京': 'city-bj/', }
        try :
            cityID = citys[self.city]
        except:
            cityID = ""
        url = "https://www.liepin.com/{0}zhaopin/pn{2}/?key={1}&pageSize=50".format(cityID, self.jobName, str(self.page-1))
        response = requests.get(url, headers = HEADERS)
        html = etree.HTML(response.text)
        joblist = html.xpath('//ul[@data-selector="result-list"]/li')
        jobs=[]
        for job in joblist:
            try:
                #逐字段解析
                jobs.append(jobinfo)
            except:
                pass
        return jobs   
  • 求职助手类:定义了一个助手类,初始化函数中首先通过pyside2库关联QT designer界面,并重点实现了“一键查询”功能。在查询功能函数中,首先判断用户选用的哪个招聘平台,并调用前面爬虫类中的相应方法,尔后根据用户指定的城市、职业和爬取数量信息,循环调用爬虫方法,并将回传结果显示输出和保存至csv文件。
代码语言:javascript
复制

class JobHelper(object):
    def __init__(self):
        qfile_jh = QFile("ui/jobhelper.ui")
        qfile_jh.open(QFile.ReadOnly)
        qfile_jh.close()
        self.ui = QUiLoader().load(qfile_jh)
        self.ui.plainTextEdit.setReadOnly(True)
        self.ui.pushButton_search.clicked.connect(self.search)
        self.ui.pushButton_clear.clicked.connect(self.clearJobs)

    def search(self):
        Web = self.ui.comboBox_PT.currentText()
        if self.ui.radioButton_select.isChecked():##常用城市列表
            city = self.ui.comboBox_citys.currentText()
        elif self.ui.radioButton_enter.isChecked():##手动输入城市
            city = self.ui.lineEdit_cityInput.text()
            if not city.strip():
                QMessageBox.about(self.ui,'Warning',"请输入城市")
                return
            else :
                try:
                    with open("ui/location.txt","r") as f:
                        citys = f.read()
                    citys = citys.split("\n")
                    if city not in citys:
                        QMessageBox.about(self.ui,'Warning',"输入城市可能有误…")
                        return
                except:
                    QMessageBox.about(self.ui,'Warning',"读取城市列表失败")
                    return
        else:##未做任何选择
            QMessageBox.about(self.ui,'Warning',"请选择城市")
            return
        #读取待查询职业
        jobName = self.ui.lineEdit_jobName.text()
        if not jobName.strip():
            QMessageBox.about(self.ui,'Warning',"请输入待查询职业")
            return
        return

    ###循环调用爬虫,并显示输出和文件保存

    def clearJobs(self):
        self.ui.plainTextEdit.setPlainText("")
        return


  • 检索结果对齐显示:这是整个界面实现过程中耗时较长的过程,为了实现结果输出的美观性,选择左对齐输出,然而python在识别中文字符和英文字符时都计入1个长度,但显示的位宽却是2倍的关系,参考了网上的做法,将中文字符单独计算,重新设计求字符串长度函数,并根据目标位宽进行截断(超出部分用“…”代替)或者空格补齐。
代码语言:javascript
复制
def mylen(s):
    mylen = len(s)
    for c in s:  # 判断字符串内汉字的数量,有一个汉字增加一个长度
        if u'\u4e00' <= c <= u'\u9fa5':
            mylen += 1
            return mylen

def setstr(s, length):
    if mylen(s) <= length:
        return s + ' ' * (length - mylen(s))
    else:
        for index in range(int(length / 2) - 4, length - 3):
            ss = s[0:index]
            if mylen(ss) >= length - 3:
                break
            return ss + "." * (length - mylen(ss))
  • 其他功能,包括平台求职信息少于用户待爬取数量、爬虫失败等。

03 运行情况

启动界面

检索结果示例

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小数志 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档