之前一直在关注句子迷这个网站,在里面可以找到自己喜欢的名人的金典语录。

每一次都去打开,再去翻页查看太烦有没有什么方法可以把网站中的句子直接抓出来,保存到本地txt文件中?
然后在网上查看了一些资料,自己动手写了一个控制台应用程序。

注:代码存在点问题,多次发起请求,线程会被占用,目前没有解决;求救中

具体实现方式:

步骤1:通过HttpWebResponse发送一个请求,将整个HTML页面请求过来,将全部数据读入StreamReader中,下图HTML代码

步骤2:将读入流中的数据进行处理,只取包含句子的文本,这里面需要查询页面的中html。

在取文本的过程中,使用正则表达式,取出想要的数据

///正则表达式
 Regex regText = new Regex(@"<div\s+class\=\""views-field-PHPcode-1\"">([\S\s]*?)</div>",RegexOptions.IgnoreCase);

步骤3:对上面的标签,在进一步进行提取

Regex objRegExp = new Regex("<(.|\n)+?>");

具体代码如下:

class Program
    {
        static ReaderWriterLock writeLock = new ReaderWriterLock();
        const int LOCK = 1000; //申请读写时间
        const int SLEEP = 100; //线程挂起时间
        static void Main(string[] args)
        {
             Console.WriteLine("-------------------句子迷文档下载----------");
            Console.WriteLine("操作API:");
            Console.WriteLine("注释1:查询的的作者名,以逗号(英文)隔开,例子如下:");
            Console.WriteLine(" 鲁迅,胡适,顾城");

            Console.WriteLine("注释2:保存的盘符,例子如下:");
            Console.WriteLine(" X:\\\\句子迷 ");
            Console.WriteLine("-------------------文档结束----------");
            Console.WriteLine("请输入需要保存的盘:");
            directoryName1 = Console.ReadLine();

            Console.WriteLine("请输入作者姓名:");
            string writers = Console.ReadLine();
            string[] strWriter = writers.Split(',');
            //string[] strWriter = { "鲁迅","胡适","belle","stars" };
            for (int i = 0; i < strWriter.Length; i++)
            {
                Thread thread = new Thread(DownLoad1);
                thread.Name = strWriter[i];
                thread.Start();
            }

            Console.ReadKey();


        }

        #region 通过网页获取句子迷中的名言名句
        /// <summary>
        /// 通过网页获取句子迷中的名言名句
        /// </summary>
        /// <param name="category"></param>
        public static void DownLoad1()
        {
            string url = string.Empty;
            bool flag = true;//遇到取文件异常就直接跳出

            for (int pageSize = 0; pageSize < 10; pageSize++)
            {
                try
                {
                    string writerName = Thread.CurrentThread.Name; ;
                    //查询作者列子
                    //if (pageSize == 0)
                    // url = "http://www.juzimi.com/writer/徐志摩";
                    //else
                    // url = "http://www.juzimi.com/writer/徐志摩?page=" + pageSize;

                    //第一版查询功能
                    //if (pageSize == 0)
                    // url = "http://www.juzimi.com/writer/"+writerName;
                    //else
                    // url = "http://www.juzimi.com/writer/" + writerName + "?page=" + pageSize;
                    if (pageSize == 0)
                        url = "http://www.juzimi.com/search/node/" + writerName + "%20type:sentence";
                    else
                        url = "http://www.juzimi.com/search/node/" + writerName + "%20type%3Asentence?page=" + pageSize;
                    //创建http链接
                    var request = (HttpWebRequest)WebRequest.Create(url);
                    //request.Timeout = 1000 * 10; //5s过期
                    var response = (HttpWebResponse)request.GetResponse();
                    Stream stream = response.GetResponseStream();
                    StreamReader sr = new StreamReader(stream);
                    string content = sr.ReadToEnd();
                    var list = GetHtmlTextList(content);
                    if (list.Count == 0)
                    {
                        Console.WriteLine("时间:" + DateTime.Now + " 当前网址:" + url + ":未找到相关信息;" + "当前线程:" + Thread.CurrentThread.ManagedThreadId);
                        flag = false;
                        break;
                    }
                    try
                    {
                        //文件保存文件夹
                        string directoryName =  string.IsNullOrEmpty(directoryName1) ? "X:\\句子迷" : directoryName1;
                        //文件名
                        string fileName = writerName;
                        Write(directoryName,fileName,list);
                        Console.WriteLine("时间:" + DateTime.Now + " 当前网址:" + url + "句子信息下载完成!" + "当前线程:" + Thread.CurrentThread.ManagedThreadId);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("时间:" + DateTime.Now + " 当前网址:" + url + " 错误信息:" + e.Message + "当前线程:" + Thread.CurrentThread.ManagedThreadId);
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    if (ex.ToString().Contains("404"))
                    {
                        Console.WriteLine("时间:" + DateTime.Now + " 当前网址:" + url + " 错误信息:" + ex.Message + "当前线程:" + Thread.CurrentThread.ManagedThreadId);
                        flag = false;
                        break;
                    }
                    else
                    {
                        Console.WriteLine("时间:" + DateTime.Now + " 当前网址:" + url + " 错误信息:" + ex.Message + "当前线程:" + Thread.CurrentThread.ManagedThreadId);
                    }
                }

                if (!flag)
                {
                    break;
                }

            }
        }

        /// <summary>
        /// 保存句子迷中的句子
        /// </summary>
        /// <param name="path">保存路劲地址</param>
        /// /// <param name="path">句子迷中的句子</param>
        public static void Write(string path,string fileName,List<string> strBook)
        {

            writeLock.AcquireWriterLock(LOCK);
            FileStream fs = null;
            //判断文件夹是否存在
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            //判断集体文件保存路径是否存在
            string filePalce = path + "\\" + fileName + ".txt";
            if (!File.Exists(filePalce))
            {
                File.Create(filePalce);
                fs = new FileStream(filePalce,FileMode.Create);
            }
            else
            {
                fs = new FileStream(filePalce,FileMode.Append);
            }

            StreamWriter sw = new StreamWriter(fs);
            foreach (var item in strBook)
            {
                //开始写入
                sw.Write(item + "\r\n\r\n");
            }
            Thread.Sleep(SLEEP);
            //清空缓冲区
            sw.Flush();
            //关闭流
            sw.Close();
            fs.Close();
            writeLock.ReleaseWriterLock();

        }


        /// <summary> 
        /// 取得HTML中所有图片的 URL。 
        /// </summary> 
        /// <param name="sHtmlText">HTML代码</param> 
        /// <returns>图片的URL列表</returns> 
        public static List<string> GetHtmlTextList(string sHtmlText)
        {
            // 定义正则表达式用来匹配 text 标签 
            Regex regText = new Regex(@"<div\s+class\=\""views-field-PHPcode-1\"">([\S\s]*?)</div>",RegexOptions.IgnoreCase);

            // 搜索匹配的字符串 
            MatchCollection matches = regText.Matches(sHtmlText);

            List<string> sUrlList = new List<string>();

            // 取得匹配项列表 
            foreach (Match match in matches)
            {
                sUrlList.Add(replceHtml(match.Value));
            }
            return sUrlList;
        }

        /// <summary>
        /// 将取出来的含有html的标签替换掉,只留下里面的值
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static string replceHtml(string strHtml)
        {
            Regex objRegExp = new Regex("<(.|\n)+?>");
            return objRegExp.Replace(strHtml,"");
        }
        #endregion

运行结果:

本地保存路径,及打开文件效果:

通过线程,HttpWebResponse,正则获取句子迷中的句子的更多相关文章

  1. iOS:核心图像和多线程应用程序

    我试图以最有效的方式运行一些核心图像过滤器.试图避免内存警告和崩溃,这是我在渲染大图像时得到的.我正在看Apple的核心图像编程指南.关于多线程,它说:“每个线程必须创建自己的CIFilter对象.否则,你的应用程序可能会出现意外行为.”这是什么意思?我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文).这在coreImage的上下文中是否有意义?

  2. ios – 多个NSPersistentStoreCoordinator实例可以连接到同一个底层SQLite持久性存储吗?

    我读过的关于在多个线程上使用CoreData的所有内容都讨论了使用共享单个NSPersistentStoreCoordinator的多个NSManagedobjectContext实例.这是理解的,我已经使它在一个应用程序中工作,该应用程序在主线程上使用CoreData来支持UI,并且具有可能需要一段时间才能运行的后台获取操作.问题是NSPersistentStoreCoordinator会对基础

  3. ios – XCode断点应该只挂起当前线程

    我需要调试多线程错误.因此,为了获得生成崩溃的条件,我需要在代码中的特定点停止一个线程,并等待另一个线程到达第二个断点.我现在遇到的问题是,如果一个线程遇到断点,则所有其他线程都被挂起.有没有办法只停止一个线程,让其他线程运行,直到它们到达第二个断点?)其他更有趣的选择:当你点击第一个断点时,你可以进入控制台并写入这应该在该断点处暂停当前上下文中的线程一小时.然后在Xcode中恢复执行.

  4. ios – 在后台线程中写入Realm后,主线程看不到更新的数据

    >清除数据库.>进行API调用以获取新数据.>将从API检索到的数据写入后台线程中的数据库中.>从主线程上的数据库中读取数据并渲染UI.在步骤4中,数据应该是最新数据,但我们没有看到任何数据.解决方法具有runloops的线程上的Realm实例,例如主线程,updatetothelatestversionofthedataintheRealmfile,因为通知被发布到其线程的runloop.在后台

  5. ios – NSURLConnectionLoader线程中的奇怪崩溃

    我们开始看到我们的应用启动时发生的崩溃.我无法重现它,它只发生在少数用户身上.例外情况是:异常类型:EXC_BAD_ACCESS代码:KERN_INVALID_ADDRESS位于0x3250974659崩溃发生在名为com.apple.NSURLConnectionLoader的线程中在调用时–[NSBlockOperationmain]这是该线程的堆栈跟踪:非常感谢任何帮助,以了解可能导致这种崩

  6. ios – 合并子上下文时的NSObjectInaccessbileExceptions

    我尝试手动重现,但失败了.是否有其他可能发生这种情况的情况,是否有处理此类问题的提示?解决方法在创建子上下文时,您可以尝试使用以下行:

  7. ios – 从后台线程调用UIKit时发出警告

    你如何处理项目中的这个问题?

  8. ios – 在SpriteKit中,touchesBegan在与SKScene更新方法相同的线程中运行吗?

    在这里的Apple文档AdvancedSceneProcessing中,它描述了更新方法以及场景的呈现方式,但没有提到何时处理输入.目前尚不清楚它是否与渲染循环位于同一个线程中,或者它是否与它并发.如果我有一个对象,我从SKScene更新方法和touchesBegan方法(在这种情况下是SKSpriteNode)更新,我是否要担心同步对我的对象的两次访问?解决方法所以几天后没有回答我设置了一些实验

  9. ios – 在后台获取中加载UIWebView

    )那么,有一种方法可以在后台加载UIWebView吗?解决方法如果要从用户界面更新元素,则必须在应用程序的主队列(或线程)中访问它们.我建议您在后台继续获取所需的数据,但是当需要更新UIWebView时,请在主线程中进行.你可以这样做:或者您可以创建一个方法来更新UIWebView上的数据,并使用以下方法从后台线程调用它:这将确保您从正确的线程访问UIWebView.希望这可以帮助.

  10. ios – 何时使用Semaphore而不是Dispatch Group?

    我会假设我知道如何使用DispatchGroup,为了解问题,我尝试过:结果–预期–是:为了使用信号量,我实现了:并在viewDidLoad方法中调用它.结果是:从概念上讲,dispachGroup和Semaphore都有同样的目的.老实说,我不熟悉:什么时候使用信号量,尤其是在与dispachGroup合作时–可能–处理问题.我错过了什么部分?

随机推荐

  1. 法国电话号码的正则表达式

    我正在尝试实施一个正则表达式,允许我检查一个号码是否是一个有效的法国电话号码.一定是这样的:要么:这是我实施的但是错了……

  2. 正则表达式 – perl分裂奇怪的行为

    PSperl是5.18.0问题是量词*允许零空间,你必须使用,这意味着1或更多.请注意,F和O之间的空间正好为零.

  3. 正则表达式 – 正则表达式大于和小于

    我想匹配以下任何一个字符:或=或=.这个似乎不起作用:[/]试试这个:它匹配可选地后跟=,或者只是=自身.

  4. 如何使用正则表达式用空格替换字符之间的短划线

    我想用正则表达式替换出现在带空格的字母之间的短划线.例如,用abcd替换ab-cd以下匹配字符–字符序列,但也替换字符[即ab-cd导致d,而不是abcd,因为我希望]我如何适应以上只能取代–部分?

  5. 正则表达式 – /bb | [^ b] {2} /它是如何工作的?

    有人可以解释一下吗?我在t-shirt上看到了这个:它似乎在说:“成为或不成为”怎么样?我好像没找到’e’?

  6. 正则表达式 – 在Scala中验证电子邮件一行

    在我的代码中添加简单的电子邮件验证,我创建了以下函数:这将传递像bob@testmymail.com这样的电子邮件和bobtestmymail.com之类的失败邮件,但是带有空格字符的邮件会漏掉,就像bob@testmymail也会返回true.我可能在这里很傻……当我测试你的正则表达式并且它正在捕捉简单的电子邮件时,我检查了你的代码并看到你正在使用findFirstIn.我相信这是你的问题.findFirstIn将跳转所有空格,直到它匹配字符串中任何位置的某个序列.我相信在你的情况下,最好使用unapp

  7. 正则表达式对小字符串的暴力

    在测试小字符串时,使用正则表达式会带来性能上的好处,还是会强制它们更快?不会通过检查给定字符串的字符是否在指定范围内比使用正则表达式更快来强制它们吗?

  8. 正则表达式 – 为什么`stoutest`不是有效的正则表达式?

    isthedelimiter,thenthematch-only-onceruleof?PATTERN?

  9. 正则表达式 – 替换..与.在R

    我怎样才能替换..我尝试过类似的东西:但它并不像我希望的那样有效.尝试添加fixed=T.

  10. 正则表达式 – 如何在字符串中的特定位置添加字符?

    我正在使用记事本,并希望使用正则表达式替换在字符串中的特定位置插入一个字符.例如,在每行的第6位插入一个逗号是什么意思?如果要在第六个字符后添加字符,请使用搜索和更换从技术上讲,这将用MatchGroup1替换每行的前6个字符,后跟逗号.

返回
顶部