dlut开源作业————比联网数据查询

#main.py
import tkinter as tk
import bilian
from time import *

class Climbgui():
    def __init__(self,windows):
        self.tk_window = windows

    def init_windows(self):
        self.tk_window.title('爬取招标信息界面')
        self.tk_window.geometry('300x350+760+280')
        self.climb_excute_key_label = tk.Label(master=self.tk_window,text='请输入要爬取的招标关键词')
        self.climb_excute_key_entry = tk.Entry(master=self.tk_window,width=20)

        self.climb_excute_page_label = tk.Label(master=self.tk_window,text='请输入要爬取的页数')
        self.climb_excute_page_entry = tk.Entry(master=self.tk_window,width=20)

        self.climb_excute_key_label.grid(row=1,column=0)
        self.climb_excute_key_entry.grid(row=2,column=0)

        self.climb_excute_page_label.grid(row=1,column=1)
        self.climb_excute_page_entry.grid(row=2,column=1)

        self.climb_excute_button = tk.Button(master=self.tk_window,text='爬取',width=10,height=1,command=self.climb)
        self.climb_excute_button.grid(row=3,column=0,columnspan=4,pady=5)

        self.climb_result_label = tk.Label(master=self.tk_window,text='执行结果')
        self.climb_result_label.grid(row=4,column=0,columnspan=4)
        self.climb_result_entry = tk.Text(master=self.tk_window,width=40,height=18)
        self.climb_result_entry.grid(row=5,column=0,columnspan=4)


    def climb(self):
        bilian.climbnum = 0
        key = self.climb_excute_key_entry.get().strip()
        page = int(self.climb_excute_page_entry.get().strip())
        begin_time = time()
        bilian.start_climb(key=key,pages=page)
        end_time = time()
        total_time = str(end_time-begin_time)
        self.climb_result_entry.delete(1.0, 'end')
        self.climb_result_entry.insert(1.0, '本次共爬取招标信息:'+str(bilian.climbnum)+'条。')
        self.climb_result_entry.delete(2.0, 'end')
        self.climb_result_entry.insert(2.0, '\n本次爬取关键词为:'+key+',爬取总页数为:'+str(page)+'。')
        self.climb_result_entry.delete(3.0, 'end')
        self.climb_result_entry.insert(3.0, '\n本次爬取结果已保存到文件:result.csv。')
        self.climb_result_entry.delete(4.0, 'end')
        self.climb_result_entry.insert(4.0, '\n本次爬取总运行时间:'+total_time+'s。')

if __name__ == '__main__':
    windows = tk.Tk()
    gui = Climbgui(windows)
    gui.init_windows()
    windows.mainloop()

#bilian.py
import re
import requests
from lxml import etree
import csv

# 存储总共爬取的条数
climbnum = 0
# 存储的数据格式
sql_data = dict(
    web = '',   #信息来源网站
    keyword = '',   #关键字
    detail_url = '',    #招标详细页网址
    title = '', #第三方网站发布标题
    toptype = '',   #信息类型
    province = '',  #归属省份
    prodect = '',   #产品范畴
    tendering_manner = '',  #招标方式
    publicity_date = '',    #招标公示日期
    expiry_date = '',   #招标截止时间
)

#csv文件的表头
CSVHEADER = ['web','keyword','detail_url','title','toptype','province','prodect','tendering_manner','publicity_date','expiry_date']

#请求时带的数据
params = dict(
    infoClassCodes='',
    rangeType='',
    projectType='bid',
    fundSourceCodes='',
    dateType='',
    startDateCode='',
    endDateCode='',
    normIndustry='',
    normIndustryName='',
    zone='',
    zoneName='',
    zoneText='',
    key='',  # keyword
    pubDateType='',
    pubDateBegin='',
    pubDateEnd='',
    sortMethod='timeDesc',
    orgName='',
    currentPage='1',  # page
)
DEFAULT_REQUEST_HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36',
    'Host':'ss.ebnew.com',
    'cookie':'loginUser=; __cfduid=daa1311ae7cd31fd395f7e3251e7770671608880455; Hm_lvt_ce4aeec804d7f7ce44e7dd43acce88db=1608880460; JSESSIONID=5644896A631BE3652EA3853BEE69DF00; Hm_lpvt_ce4aeec804d7f7ce44e7dd43acce88db=1608881105'
}

COOKIES = 'loginUser=; __cfduid=daa1311ae7cd31fd395f7e3251e7770671608880455; Hm_lvt_ce4aeec804d7f7ce44e7dd43acce88db=1608880460; JSESSIONID=5644896A631BE3652EA3853BEE69DF00; Hm_lpvt_ce4aeec804d7f7ce44e7dd43acce88db=1608881105'

def write_csv(datas):
    global CSVHEADER
    with open('result.csv','a',newline='',encoding='utf-8') as f1:
        writer = csv.DictWriter(f1,fieldnames=CSVHEADER)
        with open("result.csv", "r", newline="",encoding='utf-8') as f2:
            reader = csv.reader(f2)
            # 判断是否存在标题,不存在则写入标题
            if not [row for row in reader]:
                writer.writeheader()
                writer.writerow(datas)
            else:
                writer.writerow(datas)

def start_requests(keyword,page):
    '''
    开始请求,并返回html对象
    :param self:
    :return:
    '''
    global DEFAULT_REQUEST_HEADERS
    global params
    params['key'] = keyword
    params['currentPage'] = page
    try:
        response = requests.get(
            url='https://ss.ebnew.com/tradingSearch/index.htm',
            params=params,
            headers=DEFAULT_REQUEST_HEADERS
        )
        html = etree.HTML(response.text)
        return html
    except:
        print('未知错误')
        return None

def pagenum_get(html):
    '''
    用于提取总页数
    :param html:
    :return:
    '''
    page_num = html.xpath('//form[@id="pagerSubmitForm"]/a/text()')
    if page_num:
        return page_num

def pagedata_get(html):
    global sql_data
    global params
    global climbnum
    content_list_x_s = html.xpath('//div[@class="ebnew-content-list"]/div')
    for content_list_x in content_list_x_s:
        toptype = content_list_x.xpath('./div/i[1]/text()')
        title = content_list_x.xpath('./div/a/text()')
        publicity_date = content_list_x.xpath('./div/i[2]/text()')
        tendering_manner = content_list_x.xpath('./div[2]/div[1]/p[1]/span[2]/text()')
        prodect = content_list_x.xpath('./div[2]/div[1]/p[2]/span[2]/text()')
        expiry_date = content_list_x.xpath('./div[2]/div[2]/p[1]/span[2]/text()')
        province = content_list_x.xpath('./div[2]/div[2]/p[2]/span[2]/text()')

        sql_data['toptype'] = toptype[0] if toptype else None
        sql_data['title'] = title[0] if title else None
        sql_data['publicity_date'] = publicity_date[0] if publicity_date else None
        if sql_data['publicity_date']:
            sql_data['publicity_date'] = re.sub('[^0-9\-]', '', sql_data['publicity_date'])
        sql_data['tendering_manner'] = tendering_manner[0] if tendering_manner else None
        sql_data['prodect'] = prodect[0] if prodect else None
        sql_data['expiry_date'] = expiry_date[0] if expiry_date else None
        sql_data['province'] = province[0] if province else None
        sql_data['keyword'] = params['key']
        sql_data['web'] = '必联网'
        sql_data['detail_url'] = content_list_x.xpath('./div/a/@href')[0] if content_list_x.xpath('./div/a/@href') else None
        write_csv(sql_data)
        climbnum += 1

def start_climb(key,pages):
    '''
    图形界面的开始爬取集合方法
    :param key:
    :param page:
    :return:
    '''
    for page in range(1,pages+1):
        print(page)
        pagedata_get(start_requests(keyword=key,page=page))
        print('已经完成第'+str(page)+'页爬取!')


报告
目录
1 引言 1
1.1 课题背景 1
1.2 所用技术 1
2 系统分析 2
3 系统设计 2
3.1 结构分析 2
3.2 数据库设计 3
4 系统实现 4
4.1 步骤及截图 4
4.2 代码实现 6
5 结束语 9

学生信息管理系统
1 引言
1.1 课题背景
必联网是服务于招标机构、采购业主和投标商的电子招投标交易平台。服务范围涵盖了国际和国内招标的设备类、物资类、工程类、服务类等多种招标业务,其开放式平台接口可以兼容企业内部管理系统和招投标应用系统,可对接国家各级公共服务平台、行政监督平台,实现了企业内部管理。作为一个公平、公正、公开的互联网采购与招标管理平台,必联网凭借在采购与招标领域的十年研究,积累了丰富的实践经验。也因此给广大企业提供了便捷、高效的互联网采购管理技术和行业信息资讯服务,从而成就了整个采购产业链的高速流畅运转,促进采供双方的良性合作,创造了一个共享、共赢的市场环境。必联网是“全方位的资讯服务+多效的采购交易平台+管家式服务”为一体的企业采购协同工作平台。不仅有日均数万的招标采购和企业产品信息,还支持企业的在线交易协同,面积分,支持以项目管理为核心的交易统计和资源管理等功能,帮助用户实现一体化的采购供应管理。必联网给用户真实的在线推广和业务管理环境,其平台化的作业方式不仅降低企业电子商务进入成本,而且大大提高企业采供协同效率,帮助企业合理配置业务资源,拓展更多商业机会。
该软件是用来爬取必联网的招标信息,用来帮助企业来收集招标信息,比如企业的产品为计算机,它可以通过这个软件来搜索到大量计算机的招标信息 ,然后进行投标增加企业收入。

1.2 所用技术
Python是一种开源的、解析性的,面向对象的语言编程。它语法优雅,可读性强,让程序员注重功能实现,而非代码本身实现细节。现广泛运用于Web开发、运维自动化、测试自动化及数据挖掘等多个行业和领域。Python语言有很大的优势:比Java、C++简单更易于使用;比PHP易懂易学并且用途更广;比Perl更简洁的语法、更简单的设计,更具可读性、更易于维护,有助于减少Bug。但它的性能不如Java、C、C++这类编译性语言强大。因此本系统开发选用Python语言编写。

界面采用tkinter框架:
Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。Tk8.0 的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中。
爬取采用results和lxml:
lxml是python的一个解析库,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高。
参考资料:https://blog.csdn.net/cz9025/article/details/87914169
2 系统分析
本次设计用Eclipse、Django开发工具,Python语言进行学生信息管理系统的开发,主要功能有后台进行建表,与数据库同步,在数据库中存储学生信息,并有增加、删除、修改功能;用户可以通过网址输入自己的登录姓名和学号,查询其余信息。分为管理端和客户端:
管理端:管理员在后台进行学生信息增加、删除、修改等功能,将学生信息保存进数据库。
客户端:用户通过管理员给定的网址进入查询页面,输入姓名与学号查询自己的信息。
3 系统设计
3.1 结构分析
(1)根据系统分析,画出系统功能模块结构图:

图 3.1 系统功能模块结构图

(2)画出系统模块功能流程图:

图 3.2 系统功能模块流程图

3.2 数据库设计
对招标信息进行存储,用到了一张表格,如果还需要其他信息,可进行表格增加。
表1 招标详细信息
列名 功能描述 类型 字段大小 主键否
web 信息来源网站 varchar 150 否
keyword 关键字 varchar 150 否
detail_url 招标详细页网址 varchar 150 否
title 第三方发布标题 varchar 150 否
toptype 信息类型 varchar 150 否
province 归属省份 varchar 150 否
prodect 产品范畴 varchar 150 否
tendering_manner 招标方式 varchar 150 否
publicity_date 招标公示日期 varchar 150 否
expiry_date 招标截止时间 varchar 150 否

4 系统实现
4.1 步骤及截图
(1) 通过编写main.py用tkinter架构建立界面并显示:

图 4.1 建立界面

(2)爬取使用results和lxml
(3)运行结果保存至csv文件:

图 4.2 保存的招标信息

4.2 代码实现
(1)在main.py中建立一个Climbgui类,用于爬取信息,显示爬取详情,以及保存爬取信息。
class Climbgui():
def init(self,windows):
self.tk_window = windows

def init_windows(self):
    self.tk_window.title('爬取招标信息界面')
    self.tk_window.geometry('300x350+760+280')
    self.climb_excute_key_label = tk.Label(master=self.tk_window,text='请输入要爬取的招标关键词')
    self.climb_excute_key_entry = tk.Entry(master=self.tk_window,width=20)

    self.climb_excute_page_label = tk.Label(master=self.tk_window,text='请输入要爬取的页数')
    self.climb_excute_page_entry = tk.Entry(master=self.tk_window,width=20)

    self.climb_excute_key_label.grid(row=1,column=0)
    self.climb_excute_key_entry.grid(row=2,column=0)

    self.climb_excute_page_label.grid(row=1,column=1)
    self.climb_excute_page_entry.grid(row=2,column=1)

    self.climb_excute_button = tk.Button(master=self.tk_window,text='爬取',width=10,height=1,command=self.climb)
    self.climb_excute_button.grid(row=3,column=0,columnspan=4,pady=5)

    self.climb_result_label = tk.Label(master=self.tk_window,text='执行结果')
    self.climb_result_label.grid(row=4,column=0,columnspan=4)
    self.climb_result_entry = tk.Text(master=self.tk_window,width=40,height=18)
    self.climb_result_entry.grid(row=5,column=0,columnspan=4)


def climb(self):
    bilian.climbnum = 0
    key = self.climb_excute_key_entry.get().strip()
    page = int(self.climb_excute_page_entry.get().strip())
    begin_time = time()
    bilian.start_climb(key=key,pages=page)
    end_time = time()
    total_time = str(end_time-begin_time)
    self.climb_result_entry.delete(1.0, 'end')
    self.climb_result_entry.insert(1.0, '本次共爬取招标信息:'+str(bilian.climbnum)+'条。')
    self.climb_result_entry.delete(2.0, 'end')
    self.climb_result_entry.insert(2.0, '\n本次爬取关键词为:'+key+',爬取总页数为:'+str(page)+'。')
    self.climb_result_entry.delete(3.0, 'end')
    self.climb_result_entry.insert(3.0, '\n本次爬取结果已保存到文件:result.csv。')
    self.climb_result_entry.delete(4.0, 'end')
    self.climb_result_entry.insert(4.0, '\n本次爬取总运行时间:'+total_time+'s。')

(2)write_csv 方法是用来把结果保存到csv中
def write_csv(datas):
global CSVHEADER
with open(‘result.csv’,‘a’,newline=’’,encoding=‘utf-8’) as f1:
writer = csv.DictWriter(f1,fieldnames=CSVHEADER)
with open(“result.csv”, “r”, newline="",encoding=‘utf-8’) as f2:
reader = csv.reader(f2)
# 判断是否存在标题,不存在则写入标题
if not [row for row in reader]:
writer.writeheader()
writer.writerow(datas)
else:
writer.writerow(datas)
(3)start_requests方法用来开始请求并返回一个html对象
def start_requests(keyword,page):
‘’’
开始请求,并返回html对象
:param self:
:return:
‘’’
global DEFAULT_REQUEST_HEADERS
global params
params[‘key’] = keyword
params[‘currentPage’] = page
try:
response = requests.get(
url=‘https://ss.ebnew.com/tradingSearch/index.htm’,
params=params,
headers=DEFAULT_REQUEST_HEADERS
)
html = etree.HTML(response.text)
return html
except:
print(‘未知错误’)
return None

(4)pagedata_get方法是用来提取页面的数据信息
def pagedata_get(html):
global sql_data
global params
global climbnum
content_list_x_s = html.xpath(’//div[@class=“ebnew-content-list”]/div’)
for content_list_x in content_list_x_s:
toptype = content_list_x.xpath(’./div/i[1]/text()’)
title = content_list_x.xpath(’./div/a/text()’)
publicity_date = content_list_x.xpath(’./div/i[2]/text()’)
tendering_manner = content_list_x.xpath(’./div[2]/div[1]/p[1]/span[2]/text()’)
prodect = content_list_x.xpath(’./div[2]/div[1]/p[2]/span[2]/text()’)
expiry_date = content_list_x.xpath(’./div[2]/div[2]/p[1]/span[2]/text()’)
province = content_list_x.xpath(’./div[2]/div[2]/p[2]/span[2]/text()’)

    sql_data['toptype'] = toptype[0] if toptype else None
    sql_data['title'] = title[0] if title else None
    sql_data['publicity_date'] = publicity_date[0] if publicity_date else None
    if sql_data['publicity_date']:
        sql_data['publicity_date'] = re.sub('[^0-9\-]', '', sql_data['publicity_date'])
    sql_data['tendering_manner'] = tendering_manner[0] if tendering_manner else None
    sql_data['prodect'] = prodect[0] if prodect else None
    sql_data['expiry_date'] = expiry_date[0] if expiry_date else None
    sql_data['province'] = province[0] if province else None
    sql_data['keyword'] = params['key']
    sql_data['web'] = '必联网'
    sql_data['detail_url'] = content_list_x.xpath('./div/a/@href')[0] if content_list_x.xpath('./div/a/@href') else None
    write_csv(sql_data)
    climbnum += 1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值