zoukankan      html  css  js  c++  java
  • 利用requests, beautifulsoup包爬取股票信息网站

    这是第一次用requests, beautifulsoup实现爬虫,此次爬取的是一个股票信息网站:http://www.gupiaozhishi.net.cn。

    实现非常简单,只是为了demo使用的数据采集,故而基本未做任何的优化,比方说代理,并发等。但对网上较为复杂的爬虫实例而言,此节可以作为简单的入门实例参考。

    基本上爬虫的第一步都是对网页的解析,http://www.gupiaozhishi.net.cn这个网站非常简单,基本要爬取的信息的url信息均在首页上可以爬取到。

    import requests
    home = requests.get('http://www.gupiaozhishi.net.cn/',headers = {},cookies = {})
    home.encoding = 'gb2312'
    
    from bs4 import BeautifulSoup
    home_html_doc = home.text
    
    home_soup = BeautifulSoup(home_html_doc, 'lxml')
    

      通过上面的代码就已经将网页信息的html信息爬取下来,网站的默认的编码通过<meta>中的charset属性查看,由于charset = 'gb2312' ,故这边使用'gb2312'的编码方式。

    将爬取下来的html信息传入BeautifulSoup实例,以'lxml'的方式对html信息进行解析。实际练习过程中,可以使用print( home_soup.prettify())的方式,将requests获取的http文件解析成我们习惯看的html格式的内容。

    由于我此次是希望通过爬取首页信息获取所有的FAQ问题的url,所以通过下面代码获取相应的url信息。

    url_list = [] # 用于存储所有的a 标签中的href内容
    knowledge_url_list = home_soup.find_all('a')  # 抓取到网页的所有a标签的信息,存储类型为list。
    for i in knowledge_url_list:
        uri = i.get('href')  # 找到所有a标签内的 超链接信息
        url_list.append(uri)
    
    '''虽然上面已经解析出了所有的href信息,但是有很多信息并不是我们想要的,发现想要的FAQ信息的url都均有共同的特性,以.html结尾。所以选择用正则的方式剔除到不要的'''
    
    pattern_url_list =[] #用正则表达式的方式挑选符合条件的href内容
    
    import re
    for i in url_list:
        patterns =r'[a-zA-Z]+://[^s]*.html$'
        res = re.match(patterns , i)
        
        if res is not None:
            pattern_url_list.append(res.group())
    
    #最后获取符合条件的url共计242个,即242个FAQ
    

     

    成功爬取所有的信息后,我们就可以用各种方式去实现抓取所有的url信息里面的相应内容,针对一个FAQ页面的问题进行了解析处理,加上测试发现基本所有的url都可以用同样的方式去处理。特殊页面特殊处理。

    其中发现了几个问题:

      1. 字符编码问题:网页的问题中有少量的繁体字,不在gb2312的字符范围内,无法解析,出现乱码; 

      2. 有大量的内容信息中打印出来的信息有 注释内容,需要将注释内容剔除。

      3. 文本内容在一个span标签内,通过<br/>标签实现换行,少量的<p>标签的内容在内部最后。

      4. 实现过程中采用的是将文本内容用列表的方式添加,在for循环体内,list类型的可变属性导致出现数据叠加。

    下面的实现代码中实现了上面提到的几个问题,解决方法均有注释:

    from bs4 import CData
    from bs4 import element
    import json
    import os
    pattern_url_list.remove('http://www.gupiaozhishi.net.cn/stock/chaogu/200702/4958.html')
    pattern_url_list.remove('http://www.gupiaozhishi.net.cn/stock/rumen/200702/94.html')
    #以上两个url是在实际测试中发现有特殊问题的两个url,选择直接剔除,避免复杂度。
    
    question_dicts = {}
    contents_list_str = []
    #定义函数每次获取url中的问题和答案。
    
    for u in pattern_url_list:
        question = requests.get(u, headers = {}, cookies = {})
        question.encoding = 'gb18030' 
    #由于繁体在gb18030中一定有映射关系,尝试后发现中文繁体乱码现象果然解决。
        question_html_doc = question.text
        question_soup = BeautifulSoup(question_html_doc,'lxml')
        
        [s.extract() for s in question_soup(['br','p'])]  #去除不想要的br,p标签
        
        question_soup.prettify()   #测试过程中用来打印查看
        
        question_name = question_soup.meta['content']  #获取标题
        question_content = question_soup.find_all('span')[0]
        
        contents_list = question_soup.find_all('span')[0].contents
        '''每个问题页面上有三个span标签,其中每个页面上的第一个span标签内存储存了所有的答案的文本内容。'''
        
        for i in contents_list:
            if type(i) == element.Comment:
                pass #如果这一行内容是注释,清除
            else:
                if len(i) <1 or i  is None:
                    pass
                else:
                    i = i.strip()
                #  剔除空行和多余的空格键,换行符等
                
                contents_list_str.append(str(i)) #将符合条件的字符串行添加到答案内容列表中
        
        contents = ''.join(contents_list_str)   #将列表内字符串拼接为一个字符串
        question_dicts[question_name] = contents  #将标签和内容添加到字典中
        
        
        contents_list_str = [] #在下一次循环前,清空列表。防止元素叠加
    

      

    最后将返回的字典内容写到文件中,目前采用的是json格式的:

    # 将返回的内容写到文件
    with open(os.path.dirname(__file__)+'/ff.json','w') as fp:
        json.dump(question_dicts,fp)
    

      

    如果要读取:

    import json
    f=open('ff.json','r',encoding='utf8')
    data=json.loads(f.read())
    print(data)
    f.close()
    

      

  • 相关阅读:
    Freemarker进行非空处理
    Freemarker导出带多个不重复图片的word
    Freemarker导出带图片的word
    怎样在Android本地视频播放器开发
    详细解说九宫图比较常用的多控件布局
    POJ 3189 Steady Cow Assignment【网络流】
    C++获取文件大小常用技巧
    operation is executing and cannot be enqueued
    Android 异步链式调用设计
    LINUX编程学习笔记(十三) 遍历目录的两种方法
  • 原文地址:https://www.cnblogs.com/zoe233/p/8044128.html
Copyright © 2011-2022 走看看