一个Python小白5个小时爬虫经历 【续】

前言

  昨天实现了python简单的数据采集之后本来还挺高兴的,结果发现在.NET读取txt文件后反序列化总是报错。具体错误原因好像是从txt读取数据之后会自动加一个隐藏的字符串,没错,肉眼看不见,就导致不是合法的json格式,最终失败。不说了,反序列化浪费了我大量的时间,下面进入正题。

代码重构

  问题就出来保存上,所以保存的文件我首先把 .txt 换成 .json 文件,后来在仔细看生成的文档,发现少了中括号[]和每条数据之间的逗号。于是乎,修改后的代码如下。 

复制代码
import match
import os
import datetime
import json

def writeToTxt(list_name,file_path):
    try:
        #这里直接write item 即可,不要自己给序列化在写入,会导致json格式不正确的问题
        fp = open(file_path,"w+",encoding='utf-8')
        l = len(list_name)
        i = 0
        #添加左中括号
        fp.write('[')
        for item in list_name:
            #直接将项目write到 json文件中
            fp.write(item)
            #添加每一项之间的逗号
            if i<l-1:
                fp.write(',\n')
            i += 1
        fp.write(']')
        #添加右中括号
        fp.close()
    except IOError:
        print("fail to open file")

#def getStr(item):
#之前用这段代码处理item,后来发现,不用处理,直接保存反而更好,自己处理了,会导致博客中乱七八糟的字符影响反序列化
#   return str(item).replace('\'','\"')+',\n'

def saveBlogs():
    for i in range(1,2):
        print('request for '+str(i)+'...')
        blogs = match.blogParser(i,10)
        #保存到文件
        path = createFile()
        writeToTxt(blogs,path+'/blog_'+ str(i) +'.json')
        print(''+ str(i) +'页已经完成')
    return 'success'

def createFile():
    date = datetime.datetime.now().strftime('%Y-%m-%d')
    path = '/'+date
    if os.path.exists(path):
        return path
    else:
        os.mkdir(path)
        return path

result = saveBlogs()
print(result)
复制代码

  最终生成了完美的json。下图只粘贴其中一项,当然是我昨天发的那篇啦。PS 前篇地址:http://www.cnblogs.com/panzi/p/6421826.html

  

转战.NET CORE

   终于把数据格式搞定了。下面就是到数据的事情了,很简单,不过在写代码过程中顺便看了一下 .NET Core的文件系统[3]:由PhysicalFileProvider构建的物理文件系统 。然后进行实战。首先,json都存放在在文件中,肯定要遍历文件了。

  

  从那篇博客中copy部分代码,来实现文件系统的访问和解析。

  定义IFileManager 接口

public interface IFileManager
    {
        /// <summary>
        /// 读取文件,获取文件内容
        /// </summary>
        /// <param name="fileHandler"></param>
        void HandleFile(Action<string> fileHandler);
    }

  然后实现接口内容,主要呢,第一,遍历文件夹得到文件,然后输出相应的文件内容。第二,反序列化文本内容转成实体。第三,加入到Elastisearch中。

复制代码
     public IFileProvider FileProvider { get; private set; }

        public FileManager(IFileProvider fileProvider)
        {
            this.FileProvider = fileProvider;
        }

        public void HandleFile(Action<string> fileHandler)
        {
            //通过FileProvider读取文件,遍历
            foreach (var fileInfo in this.FileProvider.GetDirectoryContents(""))
            {
                //读取文件内容(json)
                string result = ReadAllTextAsync(fileInfo.Name).Result;
                //执行处理
                fileHandler(result);
            }


        }
复制代码

  以上为FileManger部分代码。

  然后反序列化得到的文本内容。

复制代码
         //遍历已经搜集好的json文档
            manager.HandleFile(json =>
            {
                //反序列化得到实体
                var entities = serializer.JsonToEntities<DotNetLive.Search.Entities.CnBlogs.Blog>(json);
                //批量添加到ES中
                int result = search.IndexMany(entities);

                Console.WriteLine("加入" + result + "数据");
            });
复制代码

  当然,程序启动的时候要注册相应的服务。

复制代码
    public static IServiceProvider RegisterServices() {

            string folder = DateTime.Now.ToString("yyyy-MM-dd");
            var service = new ServiceCollection()
                //定位到文件夹,当前日期
               .AddSingleton<IFileProvider>(new PhysicalFileProvider($@"D:\{folder}"))
               .AddSingleton<IFileManager, FileManager>()
               //序列化器 
               .AddSingleton<ISerializer,CnBlogsSerializer>()
               .BuildServiceProvider();
            return service;    
        }
复制代码

运行结果

  

  至于为什么是180条,因为我在python获取接口的时候写的是 for in range(1,10),每次请求接口返回20条,请求了9次,然后合并成一个json文件存储。

  好的,最后在看一下ES中的数据:

  

 

 总结

  纸上得来终觉浅,绝知此事要躬行。这句话一点没错,看和做真是两码事。不过还好,数据采集阶段就告一段落了。不扯了,跑程序去了。小伙伴们下期再见。

  github代码参见:https://github.com/dotnetlive/dotnetlive.search/tree/master/src/Tools/cnblogs  PS:有兴趣的小伙伴可以加入dotnetlive团队。无薪,可学习,哈哈。

 

posted @   丶Pz  阅读(3689)  评论(4编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示

目录

目录

X
+

"大爷常来玩呀"

微信支付