2、苏宁百万级商品爬取 思路讲解 类别页数爬取

通过上述章节内容,我们得到了类别的数据,现在我们需要对每个类别进行商品的爬取。点击移动电源,进行商品总页数抓取,这个模块相对简单,正好适合用来练手。 我们可以从“列表页.png”的图片中看到,当前移动电源的页数为右上角所显示 1/100,即100页. xpath的获取如第三张图所示,结果为 //*[@id="second-filter"]/div[2]/div/span

类别.png

列表页.png

xpath.png

分析出了如果获取页数,我们现在要考虑的问题是,如果更新所有的类别。 其实思路非常简单,从数据库中取出对应的等级为3的类别(最底层类别),对这些类别进行循环,参数就是当前行的url,然后执行网页爬取代码,得到页数,更新数据。

数据库类别数据.png

根据Sql语句,得到等级为3的类别一共有4197个。这个时候就存在问题了,如果同步执行(循环一个一个执行),那么我的效率就很低,为了验证自己的写法。我以50个类别为例做了一个小demo测试性能。

     //获取符合条件的列表
     var urlList = _categoryService.GetListByLevel(3).Select(u => u.Url).ToList();

CategoryPageAnalysis.GetData(string url) 方法为获取类别个数方法

同步

循环执行,耗时18233毫秒

            var dics = new Dictionary<string, int>();
            foreach (var url in urlList)
            {
                dics.Add(url, CategoryPageAnalysis.GetData(url));
            }

异步方法

6163毫秒 3倍的效率差 异步方法体的说明如下: 首先因为存在4197个类别,需要对这些类别进行分类。 4197/2000 约等于20. 即开20个线程,每个线程执行200条数据

            int pageNum = 200;
            int pageCount = urlList.Count % pageNum == 0 ? urlList.Count / pageNum : urlList.Count / pageNum + 1;
            var pageListCollection = new List<List<string>>();
            for (int i = 0; i < pageCount; i++)
            {
                var pageList = urlList.Skip(i * pageNum).Take(pageNum).ToList();
                pageListCollection.Add(pageList);
            }
            Console.WriteLine(pageCount);

            //异步 6163毫秒 3倍的效率差
            int pageIndex = 1;
            List<Task> taskList = new List<Task>();
            foreach (var pageList in pageListCollection)
            {
                try
                {
                    Task task = Task.Factory.StartNew(() =>
                    {
                        var dics = new Dictionary<string, int>();
                        foreach (var url in pageList)
                        {
                            dics.Add(url, CategoryPageAnalysis.GetData(url));
                        }

                        lock (lock_obj)
                        {
                            _categoryService.BatchUpdatePage(dics);
                        }
                    });
                    taskList.Add(task);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"button3_Click 异步{ex.Message}");
                }
            }

存在的问题:

这种方法是为了单独解决这个问题而使用的,很笨拙,因为如果只有200个类别,多线程的意义就没有办法体现出来,这一点在之后的编码中我进行了修改。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WOLFRAM

交互式查询化学键信息

26830
来自专栏图形学与OpenGL

WebGL画点程序v1

本文程序实现画一个点的任务,如下图。其中,点的位置直接给定(“硬编码”)在顶点着色器中。

8530
来自专栏应兆康的专栏

100个Numpy练习【2】

翻译:YingJoy 网址: https://www.yingjoy.cn/ 来源: https://github.com/rougier/numpy-100...

568100
来自专栏大前端_Web

深入理解xhr的responseType中blob和arrayBuffer

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

30240
来自专栏数据结构与算法

洛谷P2252 取石子游戏(威佐夫博弈)

题目背景 无 题目描述 有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是...

47770
来自专栏salesforce零基础学习

salesforce 零基础学习(六十八)http callout test class写法

此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode...

31370
来自专栏marsggbo

Udacity并行计算课程笔记-The GPU Hardware and Parallel Communication Patterns

本小节笔记大纲: 1.Communication patterns gather,scatter,stencil,transpose 2.GPU hardwa...

24060
来自专栏数据星河

建模常用的pandas语句

  pandas对象是Python常用的数据分析模块,它主要包括series对象,dataframe对象和index对象。每种对象都有自己所特有的方法和属性。今...

6100
来自专栏应兆康的专栏

100个Numpy练习【1】

翻译:YingJoy 网址: https://www.yingjoy.cn/ 来源: https://github.com/rougier/numpy-100...

1.3K90
来自专栏应兆康的专栏

100个Numpy练习【2】

Numpy是Python做数据分析必须掌握的基础库之一,非常适合刚学习完Numpy基础的同学,完成以下习题可以帮助你更好的掌握这个基础库。

51190

扫码关注云+社区

领取腾讯云代金券