V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
santiagohz
V2EX  ›  Python

爬取深圳小汽车摇号每期个人竞价数据

  •  
  •   santiagohz · 2018-11-29 23:14:23 +08:00 · 3394 次点击
    这是一个创建于 1973 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 背景

    坐标深圳,摇号 24 个月了,感觉仍遥遥无期,准备转竞价。
    正好最近学习 python,学习写个爬虫把历史每期竞价数据爬出来,作为后面的竞价依据。

    • 思路

    1. 找到摇号官网 [http://xqctk.sztb.gov.cn/wxlm/index.html],使用 bs4 来处理。
    2. 从竞价结果页面获取每期竞价信息。由于这个页面没有格式,只好全面使用正则来匹配需要的竞价数据。
    3. 把爬取到的竞价数据导入到 excel 进行直观分析。(还没完成)
    • 代码

    边看书边上网搜索,一行行比照敲出来的代码。
    目前能跑通已经是极限了。美观和性能就暂时不考虑了。。
    如果有高手愿意随手优化一下,非常欢迎 post 出来,我正好可以对照学习学习。

    import requests
    import re
    from bs4 import BeautifulSoup
    
    
    def get_html(url):  # 获取网页
        try:
            res = requests.get(url)
            res.encoding = 'utf-8'  # 指定网页的编码格式
            res.raise_for_status()
            return res.text  # 返回网页文本
        except Exception as exc:
            print('获取网页出错了:%s' % (exc))
    
    
    def get_price(url):  # 获取摇号信息,通过正则匹配页面文字
        html = get_html(url)
        soup = BeautifulSoup(html, 'lxml')
        str = soup.find_all('span')  # 大部分价格信息放在 span 中,个别除外
        mytext = ''
        for i in str:  # 将解析的网页文案,拼接成整个字符串
            mytext = mytext + i.get_text()
        results = []
        time = re.match('(\d+)年第(\d+)期深圳市小汽车增量指标竞价结束', mytext)
        results.append(re.sub('\D', '', time.group()))  # 匹配摇号日期,使用 sub 方法\D,只保留数字
        results.append(re.search('个人增量指标(\d+).*?单位增量指标', mytext))
        results.append(re.search('本期参与竞价的有效编码个人为(\d+).*?个。', mytext))
        results.append(re.search('两次平均报价分别.*?(\d+).*?单位(\d+)元。', mytext))
        results.append(re.search('两次平均报价分别.*?;个人(\d+)元、', mytext))
        results.append(re.search('本期个人竞价.*?最低成交价(\d+)元、平均成交价(\d+)元 /个,', mytext))
        results.append(re.search('本期个人竞价.*?成交结果:最低成交价\d+元、平均成交价(\d+)元 /个,', mytext))
        yh_result = {}
        yh_result['期次:'] = int(results[0])
        yh_result['个人竞价指标总量:'] = int(results[1].group(1))
        yh_result['个人竞价人数:'] = int(results[2].group(1))
        yh_result['第 1 次报价均价:'] = int(results[3].group(1))
        yh_result['第 2 次报价均价:'] = int(results[4].group(1))
        yh_result['最低成交价:'] = int(results[5].group(1))
        yh_result['平均成交价:'] = int(results[6].group(1))
        return yh_result
    
    
    def get_content(url):
        contents = []
        html = get_html(url)
        soup = BeautifulSoup(html, 'lxml')
        liTags = soup.find_all('a', attrs={'class': 'am-list-item'})
        for liTag in liTags:
            content = {}
            text = '竞价情况'
            if text in liTag.get_text():  # 根据字符串匹配出摇号结果页面
                try:
                    content['title'] = liTag.get_text()
                    content['detail_url'] = liTag.get('href')
                    content['摇号结果'] = get_price(content['detail_url'])
                    contents.append(content)
                except Exception as exc:
                    print('解析网页出错了:%s' % (exc))
        return contents
    
    
    def Out2File(contents):
        with open('深圳摇号竞价结果.txt', 'a') as f:
            for content in contents:
                f.write('标题:%s\n 链接:%s\n 结果:%s\n\n' %
                        (content['title'], content['detail_url'], content['摇号结果']))
    
    
    def main(url):
        contents = get_content(url)
        Out2File(contents)
    
    
    if __name__ == '__main__':
        url = 'http://xqctk.sztb.gov.cn/wxlm/index.html'  # 第 1 页单独处理,url 格式不一样
        main(url)
        for x in range(2, 12):  # 信息一共 11 页,2-11 页 url 格式相同
            url = 'http://xqctk.sztb.gov.cn/wxlm/index_%s.html' % x
            main(url)
        print('所有的信息都已经保存完毕!')
    
    3 条回复    2018-11-30 21:53:52 +08:00
    MessyInk
        1
    MessyInk  
       2018-11-30 17:15:01 +08:00
    有个总结就好了。
    lands
        2
    lands  
       2018-11-30 17:44:47 +08:00
    摇了 6 期了, 遥遥无期...
    meowoo
        3
    meowoo  
       2018-11-30 21:53:52 +08:00
    @lands 我摇了 37 期了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1005 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:01 · PVG 04:01 · LAX 13:01 · JFK 16:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.