文本分析之数据收集

做文本分析时,在很多情况下,需要我们自己去爬外部网站的数据,由于不同的网站有不同的网页结构,所以处理起来就需要根据网页不同去做解析。解析网页使用的语言为python,因为他们提供了很多的类似插件的工具包,最终比较一下,使用的是requests包和soupy包,网页爬的数据做为以后文本分析处理的基础,关于本篇文章使用的工具包的相关参考文档如下:

http://www.python-requests.org/en/latest/

http://soupy.readthedocs.org/en/stable/index.html

下面以两个例子来说明:

解析豆瓣网站的书评,把用户评分,评分时间和评分内空取出来,并保存成cvs格式的文档。爬豆瓣网书评时需要注意服务器会返回403错误,还有就是保存文件时可能会因为编码问题导致csv文件保存失败。实现部分请直接看代码:

我们以http://book.douban.com/subject/26425831/comments/为例,做数据抓取:

def get_db_book_review(data_list, item_id, page):
    # 需要抓取网页的URL地址
    target_url = "http://book.douban.com/subject/" + str(item_id) + "/comments/hot?p=" + str(page)
    logging.info("当前抓取的网页地址为:" + target_url)
    # 设置User-Agent,如果没有配会报403错误
    client = requests.session()
    client.headers = {'User-Agent': 'Reddit API - update profile'}
    target_response = client.get(target_url)
    logging.info(target_response.status_code)
    if (200 == target_response.status_code):
        douban_html = Soupy(target_response.content, "html.parser")
        #使用类似jquery查找的方式来解析网页
        review_items = douban_html.find(id='comment-list-wrapper').find('div', 'comment-list hot ').find('ul').find_all('li')
        logging.info(review_items.count().val())
        for review in review_items:
            #每一条评论的字典,按cvs官方文档的要求传数据
            review_dic = {}
            user_stars = ""
            user_date = ""
            user_comment = ""
            user_stars_date = review.find('span', 'comment-info').find_all('span')
            user_comment = review.find('p', 'comment-content').text.val()
            if user_stars_date.count().val() == 2:
                user_stars = user_stars_date[0].attrs.val().get("class")[1]
                user_date = user_stars_date[1].text.val()
            if user_stars_date.count().val() == 1:
                user_date = user_stars_date[0].text.val()
            review_dic["UserStar"] = user_stars
            review_dic["userDate"] = user_date
            review_dic["UserComment"] = user_comment
            data_list.append(review_dic)
    else:
        logging.info("服务器暂时无法访问!")

    logging.info("=========当前处理数据完毕==================")


def export_data_to_csv(data_list, item_id):
    # 设定文件的编码
    with open(str(item_id) + '.csv', 'w', encoding='utf-8') as csv_file:
        fieldnames = ['UserStar', 'userDate', 'UserComment']
        dict_writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        dict_writer.writeheader()
        dict_writer.writerows(data_list)

#item_id是书的id号
#total_page是取多少页的数据
def get_data_by_id_pages(data_list, item_id, total_page):
    for page in range(1, total_page + 1):
        get_db_book_review(data_list, item_id, page)
        # 为了避免被服务器封ip,每间隔10秒钟抓一次数据
        time.sleep(10)
    export_data_to_csv(data_list, item_id)


data_list = []
get_data_by_id_pages(data_list, 26425831, 10)

生成的csv文件如下:


解析腾讯新闻的列表页,并根据列表页上的新闻的url去获取新闻详情,并保存在文本文件中。解析新闻详情时,需要过滤掉视频相关的html代码。实现部分请直接看代码:

腾讯新闻的首页为http://news.qq.com/,需要自己去找对应的html列表页:

#根据新闻列表抓取对应的新闻详情并生成文件
def get_qq_news(page):
    #设定抓取数据的列表页
    target_url = "http://news.qq.com/c/816guonei_"+str(page)+".htm"
    logging.info("当前抓取的网页地址为:" + target_url)
    target_response = requests.get(target_url)
    #打印服务器返回的状态码
    logging.info(target_response.status_code)
    target_html = Soupy(target_response.content, "html.parser")
    #类似用jquery的形式找出列表对应的html标签
    news_list = target_html.find_all('div',"Q-tpList")
    logging.info(news_list.count().val())
    for news in news_list:
        #新闻标题
        news_title = news.find("div", "Q-tpWrap").find("em").find("a").text.val()
        logging.info(news_title)
        #新闻详情URL
        detail_url = news.find("div", "Q-tpWrap").find("em").find("a").attrs.get("href").val()
        detail_request_url = "http://news.qq.com"+detail_url
        logging.info(detail_request_url)
        detail_response = requests.get(detail_request_url)
        detail_news_html = Soupy(detail_response.content.decode("gbk"), "html.parser")
        #根据id='Cnt-Main-Article-QQ'找出对应的内空,因为非p标签的可能是js或视频html代码,需要过滤掉
        detail_news_p_items = detail_news_html.find(id='Cnt-Main-Article-QQ').find_all('p')
        news_content_data = ""
        for p_item in detail_news_p_items:
            logging.info(p_item.children.each(Q.text.strip()).filter(len).val())
            news_content_data = news_content_data + str(p_item.children.each(Q.text.strip()).filter(len).val())
        write_text_file(detail_url,str(news_content_data))


#根据文件路径和传入的数据生成文本文件
def write_text_file(file_path,file_data):
    file_ext = get_file_extension(file_path)
    if len(file_path)==0:
        return False
    else:
        current_dir = os.getcwd()
        dir_array = file_path.split("/")
        for index,item in enumerate(dir_array):
            if len(item)>0 :
                current_dir = current_dir +"\\" +item
                if index==len(dir_array)-1:
                    file = open(current_dir.replace(file_ext,'.txt'),mode='w')
                    file.write(file_data)
                    file.close()
                else:
                    if os.path.isdir(current_dir)==False:
                        os.mkdir(current_dir)

#静态页后缀
def get_file_extension(path):
  return os.path.splitext(path)[1]


get_qq_news(1)


腾讯新闻解析出来的是一个文件夹的列表:




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值