欢迎访问的小伙伴! 希望在这里能帮到你。有问题请多多指教~ 点击联系站长

陕西政府采购网爬虫,python+selenium动态爬取

Python 焦康阳 0评论

大家好,我是小焦。今天我们来看一看陕西省政府采购网(http://www.ccgp-shaanxi.gov.cn/)的数据怎么爬取?因为公司要看一看采购项目,挨个一个一个点的话比较麻烦。我们刚好可以用代码来自动帮我们完成数据的筛选,节省大量的时间。

    提前声明一下,我写这个代码只是为了个人方便,读者切勿用作非法或者商业用途使用。

任务目标:

    首先我们本次爬虫的任务是完成该网站的采购招标信息爬取,省去人工耗费的时间。快速筛选出我们的需要的指定信息。然后将招标信息的标题、链接、和时间找出来,并保存。

准备工具:

  •  python3
  • chrom浏览器及dirver驱动
  • mysql
  • pyquery、selenium、等库的了解

思路:   

 当我们完成上述的准备工作之后就是研究目标网站的结构了。通过简单的点击查看等操作,我们发现这个网站是一个动态网站,对应的内容都是javascript来动态加载的,普通的requests肯定不能获取到随时变化的内容了。所以我们选择selenium工具来模仿人的点击操作,获取网页源码,然后提取出对应的信息了。

上述的页面就是我们要获取的页面。先是选择信息公告,然后选择对应的区域,我们的目标区域内容是动态加载的。它就是我们最终目标。由于招标文件太多,也不好排版,我们只需拿到想要的招标题目、链接、日期就可以了。

    由于我们要获取指定的市区招标文件,我们要借助selenium模仿浏览器点击操作,点击我们想要的城市,然后目标区域的内容会自动变化,我们在进行区域的信息筛选就能达到我们的目的了。

    好的,不多说了,大家看看代码吧。

# 2020.9.13日
# 本次爬虫主要是实现陕西政府采购网的爬虫
# 该爬虫以技术交流为准,切勿用于任何非法用途,后果自负
# 我的个人博客:https://jiaokangyang.com
​
from selenium import webdriver
import pymysql
import time
from pyquery import PyQuery as pq
from docx import *
​
# 由于该网站是javascript来异步加载的,而且requests不能正常获取,这里我们使用selenium爬取
​
url = 'http://ccgp-shaanxi.gov.cn/notice/list.do?noticetype=3&province=province'
shuru = input('请输入要爬取的区域名称,确保在网站的范围内:')
shuru2 = input('请输入上述城市中要筛选的区域名:\n(如不需要筛选则直接敲击回车键开始抓取)\n')
# 创建一个空文档,用于后面的文档保存
document = Document()
​
# 链接数据库
conn = pymysql.connect(host='localhost',user='root',password='123456',port=3306,database='shanxi')
# 获取游标,后面进行sql语句的执行
cursor = conn.cursor()
#  如果表不存在则创建一个名为shuju的表。这里切记mysql中的列名字不需要加双引号。
cursor.execute("create table if not exists shuju(id int not null auto_increment primary key,title varchar(50) not null,url varchar(100) not null,riqi varchar(20) not null);")
​
​
# 打开谷歌浏览器
brower = webdriver.Chrome()
# 打开采购信息的网页
​
brower.get(url)
# 打开网页后,点击对应城市的标签,然后异步加载的内容进行加载。
if shuru != '':
    brower.find_element_by_link_text(shuru).click()
# 这块由于代码自动操作太快,有时出现内容没更新的情况,所以我们等待两秒
time.sleep(2)
​
​
# 该函数完成单页内容的采集输出
def get_onepage(html):
    html = pq(html)
    a = '[' + shuru2 + ']'
    lists = html('.list-box table tbody tr').items()
    for list in lists:
        if shuru2 != '':
            b = list('td:nth-child(2)').text() # 使用pyquery的伪类用法查找第二个元素内的名字
            if b == a:  # 对比分析,如果和我们输入的区域名字相同,则打印出来
                title = list('td a ').text()
                url = list('td a ').attr('href')
                date = list('td:last-child').text()
                # 如需写入word,请将getmysql方法换成get_word即可
                getmysql(title,url,date)
​
​
        else:
            title = list('td a ').text()
            url = list('td a ').attr('href')
            date = list('td:last-child').text()
            getmysql(title, url, date)
​
# 上面完成单页信息的采集,现在进行前五页的信息采集。
def get_page():
    for i in range(1,6):
​
        print('开始抓取第%s页'%i)
        # 由于第一页不用点击操作我们从第二页开始进行点击操作
        if i > 1:
            brower.find_element_by_link_text(str(i)).click()
            # 这块停顿两秒,让页面内容顺利加载出来
            time.sleep(2)
        html = brower.page_source
        get_onepage(html)
​
        print('抓取第%s页完毕'%i)
​
    brower.close()
​
# 该函数将获取到的内容写入到word文件中
​
def get_word(title,url,date):
​
    document.add_paragraph(title)
    document.add_paragraph('网址:' + url)
    document.add_paragraph(date + '\n')
​
# 此函数将爬到的数据最近写到word中
def execute():
    # 给文档添加标题
    header = '{}{}招标项目清单'.format(shuru,shuru2)
    document.add_heading(header,level=0)
    # 运行爬虫程序
    get_page()
    # 将爬到的数据保存
    document.save('{}{}招标清单.docx'.format(shuru,shuru2))
​
# 该函数完成将数据写入mysql的操作
def getmysql(title,url,date):
    sql = "insert into shuju(title,url,riqi) values('%s','%s','%s')" %(title, url, date)
    # 执行sql语句
    cursor.execute(sql)
​
​
# 执行数据库写入操作
def main():
    # 执行get_page函数,将所有的数据写入到数据库
    print('开始执行爬虫')
    get_page()
    print('爬虫执行完毕,并关掉数据库')
    # 提交数据,关闭数据库
    conn.commit()
    conn.close()
​
​
main()

上述代码看似混乱,其实非常简单,我只要是写了一个单页的采集函数,然后就再写了一个前五页的函数,其次就是写入word的函数和数据库的。也是边学边摸索。

效果展示:

word写入效果
数据库写入

github地址:https://github.com/zhanjiuyou/shanxicg.git

声明:代码虽烂,但请读者切勿用作非法用途,后果自负

喜欢 (1)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址