爬虫+sql server+node+vue3+leaflet+supermap iclient,实现对医院数据的获取以及展示

刚开始是在做最近地物查询,然后突然想到可以结合前后端做一个医院信息的动态展示

首先打开iserver看一个个医院的的列表

然后随便打开一个,里面有医院的id和name,可以依据名字,然后查找医院的信息(等级还有成立时间等等)

此时观察一下上面的路径“http://localhost:8090/iserver/services/data-changchun/rest/data/datasources/Changchun/datasets/Hospital/features?fromIndex=0&toIndex=13

http://localhost:8090/iserver/services/data-changchun/rest/data/feature/0-27-0

发现第一个前面是不变的,就是fromindex和toindex两个在变。然后看第二个,就是最后的0-27-?,最后?这个数字变一下。Ok,然后打开pycharm,我们开始第一步,提取医院名字和id

import pymssql #引入对数据库操作模块
import requests #等会获得html
from bs4 import BeautifulSoup #
import re #
serverName = '127.0.0.1'
userName = 'sa'
passWord = 'xxxx' #密码
database='hosipital'
conn = pymssql.connect(server=serverName,user=userName,password=passWord,database=database)
cursor = conn.cursor()
creTab='CREATE TABLE inf ( id int, name varchar(100));' #创建一张表
cursor.execute(creTab)
startindex=0
count=0
for startindex in range(0,70,17):
    endindex=startindex+17
    baseUrl = f'http://localhost:8090/iserver/services/data-changchun/rest/data/datasources/Changchun/datasets/Hospital/features?fromIndex={startindex}&toIndex={endindex}'
    r=requests.get(baseUrl)
    r.encoding='utf-8' 
    html=r.text
    soup = BeautifulSoup(html, 'html.parser')
    tds=soup.find_all('td')
    for td in tds:
        a=td.find('a')
        if a:
            txt=a.get('href')
            if re.match('^http.*false$',txt):
                r2=requests.get(txt)
                html2=r2.text
                soup2=BeautifulSoup(html2,'html.parser')
                div=soup2.find('div',class_='bodyDIv').find('div',id="resourceContent")
                restBody=div.find('div',class_='restBody')
                table=restBody.find('table')
                td=table.find_all('tr')[2].find_all('td')[1]
                count=count+1
                print(count)
                insert = f"insert into inf (id,name) values ({count},'{td.text}')" 
                cursor.execute(insert) #写入数据库
                conn.commit()
cursor.close()
conn.close()

得到的结果差不多长这样

这里有一个查询医院数据的网站'https://y.dxy.cn/hospital',点进去搜几个医院,观察下网址变化就知道了
import requests
import pymssql
from bs4 import BeautifulSoup
import json
serverName = '127.0.0.1'
userName = 'sa'
passWord = 'xxxxx'
database='hosipital'
conn = pymssql.connect(server=serverName,user=userName,password=passWord,database=database,charset='GBK')
cursor = conn.cursor()
# de='drop table details'
# cursor.execute(de)
cursor.execute('CREATE TABLE details ( id int, name varchar(100),location varchar(100),type varchar(20),edge varchar(30),level varchar(20),time varchar(40))')
conn.commit()

cursor.execute("SELECT * FROM inf")
count=0

ls = cursor.fetchall()
for l in ls:
    count=count+1
    print(f'正在进行第{count}次')
    name = l[1]
    print(name)
    baseurl = f'https://y.dxy.cn/hospital/?page=1&name={name}&location=220000'
    r=requests.get(baseurl)
    r.encoding='utf-8'
    html=r.text
    soup=BeautifulSoup(html,'html.parser')
    num=soup.find('div',class_='data').find('span').text
    if(num=='0'):
        insert = f"insert into details (id,name) values ({l[0]},'{name}')"
        cursor.execute(insert)
        conn.commit()
    else:
        print(f'找到{num}条')
        div=soup.find('div',class_='main-listsbox')
        table=div.find('div',class_='table')
        tbody=table.find('div',class_='tbody')
        trs=tbody.find_all('div',class_='tr')
        for tr in trs:
            tds=tr.find_all('div',class_='td')
            if '长春市' in tds[1].text:
                str=tds[0].find('div',class_='hospital-title').text
                data = {
                    'id': l[0],
                    'name':str.strip(),
                    'location': tds[1].text,
                    'type': tds[2].text,
                    'edge': tds[3].text,
                    'level': tds[4].text,
                    'time': tds[6].text
                }
                insert = "insert into details (id,name,location,type,edge,level,time) values (%d, %s, %s, %s, %s, %s, %s)"
                da=(data['id'],data['name'],data['location'],data['type'],data['edge'],data['level'],data['time'])
                cursor.execute(insert,da)
                conn.commit()
cursor.close()
conn.close()



但是不知道为什么,我最后数据库里面是乱码,爬取医院名字的时候数据库那里用的是utf8编码,写进去是正常的,现在爬取医院名字的时候也是utf8编码,但是结果是乱码,我换成gbk也是乱码,不知道为什么,但是不影响下面操作,先看下乱码表

找了半天也解决不了,索性二合一,然后就行了

import requests
import pymssql
from bs4 import BeautifulSoup
import re
serverName = '127.0.0.1'
userName = 'sa'
passWord = 'xxxxx'
database='hosipital'
conn = pymssql.connect(server=serverName,user=userName,password=passWord,database=database)
cursor = conn.cursor()
cursor.execute('CREATE TABLE details ( id int, name varchar(100),location varchar(100),type varchar(20),edge varchar(30),level varchar(20),time varchar(40))')
conn.commit()
count=0
startindex=0
for startindex in range(0,70,17):
    endindex=startindex+17
    baseUrl = f'http://localhost:8090/iserver/services/data-changchun/rest/data/datasources/Changchun/datasets/Hospital/features?fromIndex={startindex}&toIndex={endindex}'
    r=requests.get(baseUrl)
    r.encoding='utf-8'
    html=r.text
    soup = BeautifulSoup(html, 'html.parser')
    tds=soup.find_all('td')
    for td in tds:
        a=td.find('a')
        if a:
            txt=a.get('href')
            if re.match('^http.*false$',txt):
                r2=requests.get(txt)
                html2=r2.text
                soup2=BeautifulSoup(html2,'html.parser')
                div=soup2.find('div',class_='bodyDIv').find('div',id="resourceContent")
                restBody=div.find('div',class_='restBody')
                table=restBody.find('table')
                td=table.find_all('tr')[2].find_all('td')[1]
                name=td.text
                count=count+1
                print(f'正在进行第{count}次')
                baseurl = f'https://y.dxy.cn/hospital/?page=1&name={name}&location=220000'
                r=requests.get(baseurl)
                r.encoding='utf-8'
                html=r.text
                soup=BeautifulSoup(html,'html.parser')
                num=soup.find('div',class_='data').find('span').text
                if(num=='0'):
                    insert = f"insert into details (id,name) values ({count},'{name}')"
                    cursor.execute(insert)
                    conn.commit()
                else:
                    print(f'找到{num}条')
                    div=soup.find('div',class_='main-listsbox')
                    table=div.find('div',class_='table')
                    tbody=table.find('div',class_='tbody')
                    trs=tbody.find_all('div',class_='tr')
                    for tr in trs:
                        tds=tr.find_all('div',class_='td')
                        if '长春市' in tds[1].text:
                            str=tds[0].find('div',class_='hospital-title').text
                            insert = "insert into details (id,name,location,type,edge,level,time) values (%d, %s, %s, %s, %s, %s, %s)"
                            da=(count,str.strip(),tds[1].text,tds[2].text,tds[3].text,tds[4].text,tds[6].text)
                            cursor.execute(insert,da)
                            conn.commit()
cursor.close()
conn.close()



然后就是nodejs

index.js里是这样,用了express,用了路由,没用中间件

const express=require('express')
const app=express()
const SqlRouter=require('./SqlRouter')
app.use('/hosipital',SqlRouter)
app.get('*',(req,res)=>
{
    res.send('网址输错了,请修改')
})
app.listen(3090,()=>
{
    console.log('begin listen')
})

sqlRouter里面是这样的

const express=require('express')
const router=express.Router()
const sql=require('mssql')
const mssql=require('mssql')
const config={
    user:'sa',
    password:'xxxx',
    server:'localhost',
    database:'hosipital',
    port: 1433,
    encrypt: false //这一步很重要
}
const query=async(num)=>
    {
        await mssql.connect(config)
        const request = new mssql.Request()
        const {recordset}=await request.query(`select * from inf where id=${num}`)
        return recordset
    }
router.get('/inf/:id',async(req,res)=>
{
    const result=await query(req.params.id)
    res.send(result)
})
router.get('*',(req,res)=>
{
    res.send("<h1>进入了医院信息首页<h1/>")
})
module.exports=router

用的mssql,里面有一个很重要的参数encrypt,刚开始一直连接失败,加上就好了,

然后异步,等数据库连接上之后,依据传入的id查数据库,也就是说等会我们发送ajax请求要带上id,后端就这些,然后看下leaflet

首当其冲的就是代理跨域在vite.config.ts

import { defineConfig } from 'vite'
import commonjs from 'vite-plugin-commonjs'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [commonjs(),vue()],
  resolve:{
    alias:{
      '@':path.resolve(__dirname,'src')
    }
  },
  server: {
    proxy: {
      "/api": {         //代理的请求
        target: "http://localhost:3090",    //后端的地址
        changeOrigin: true,                 //开启跨域访问
        rewrite: (path) => path.replace(/^\/api/,''),    //重写前缀(如果后端本身就有api这个通用前缀,那么就不用重写)
      },
    },
  }
})

我是这么理解的,就是你给代理服务器发必须要带上/api这个路径在最前面,然后代理服务器在向后端发送的时候rewrite把/api去掉,因此我们接下对axios封装要写上baseurl,下面对axios进行简单封装在utils/index.ts里面

import axios from 'axios'
const request=axios.create({
    baseURL:'/api',
    timeout:5000
})
export default request

ok封装结束,接下来就剩最后一步了,发送我是在components/Top/index.vue里面实现,下面只展示,点击marker然后弹出框展示一下名字

 L.geoJSON(re.result.features,{pointToLayer:function(geoJsonPoint:any, latlng:any) {
               let marker= L.marker(latlng,{icon:myIcon})
               marker.on('click',async function()
            {
                let content:any=await request.get(`/hosipital/inf/${geoJsonPoint.id}`)
                marker.bindPopup(`${content.data[0].name}`).openPopup()
            })
               map.value.off('click')
            return marker;
            }}).addTo(map.value)

最后结果如图

ok,结束了,如果有问题可以问我

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值