zoukankan      html  css  js  c++  java
  • python爬虫之深度爬取实例

    写了一个之前没完成的项目,代码优化不够,速度有点慢,应该也有错误的地方,望大佬看了之后能给点建议。。。。。。。。。

    这是开始的url,先看一下它的网页结构:http://www.cymodel.net/deaafc/13143.html,可以观察到,整个网页大致分为六部分内容,中间的正文部分,右边的四部分新闻板块,还有最下面的一部分社会新闻。而每一个新闻链接点进去后又是一个相同模样的页面,爬取的目标是获取到所有的新闻title和对应的url。下面是代码,每部分链接的提取都差不多,利用find_all返回结果列表,然后再对列表进行遍历。

      1 import requests
      2 from bs4 import BeautifulSoup
      3 
      4 # response请求页面的响应,all_url_lis用于存放所有页面的utl,all_title_list用于存放所有页面的title,
      5 # i用来显示当前爬取到第几个页面
      6 
      7 
      8 def parse(response, all_url_list, all_title_list, i):
      9     html = response.content  # 先获取二进制形式的内容,下面再进行转换,否则会出现中文乱码
     10     html = str(html, encoding='utf-8')
     11     soup = BeautifulSoup(html, 'lxml')  # 利用Beautifulsoup解析库
     12     f = open('title_and_url.txt', 'a', encoding='utf-8')    # 打开文件,存储所有页面的title和url
     13 
     14     # 获取正文
     15     # content = soup.find(name='div', attrs={'class': 'main_article'})
     16     # p_list = content.find_all(name='p')
     17     # for p in p_list:
     18     #     print(p.string)
     19 
     20     flag = 0    # 用来标志当前页面的url有多少已经存储过了,后面可以作为结束循环的条件
     21 
     22     # 获取下方社会新闻
     23     Sociology_list = soup.find_all(name='div', attrs={'class': 'r'})
     24     sociology_a_list = Sociology_list[0].find_all(name='a')
     25     for a in sociology_a_list:
     26         sociology_title = a.string
     27         sociology_url = a.attrs.get('href')
     28         # print(sociology_title, sociology_url)
     29         # 判断列表中是否已经存在这个页面的url或title,实现去重
     30         if sociology_url not in all_url_list and sociology_title not in all_title_list:
     31             all_url_list.append(sociology_url)
     32             all_title_list.append(sociology_title)
     33             f.write(sociology_title + '   ' + sociology_url + '
    ')
     34         else:
     35             flag += 1
     36 
     37     # 获取排行榜
     38     Ranking_list = soup.find_all(name='ul', attrs={'class': 'tt', 'id': 'tt'})
     39     rank_a_list = Ranking_list[0].find_all(name='a')
     40     for a in rank_a_list:
     41         rank_title = a.string
     42         rank_url = a.attrs.get('href')
     43         # print(rank_title, rank_url)
     44         if rank_url not in all_url_list and rank_title not in all_title_list:
     45             all_url_list.append(rank_url)
     46             all_title_list.append(rank_title)
     47             f.write(rank_title + '   ' + rank_url + '
    ')
     48         else:
     49             flag += 1
     50 
     51     # 热点推荐
     52     hot_list = soup.find_all(name='ul', attrs={'class': 'ducheng_list'})
     53     hot_a_list = hot_list[0].find_all(name='a')
     54     for a in hot_a_list:
     55         hot_title = a.string
     56         hot_url = a.attrs.get('href')
     57         # print(hot_title, hot_url)
     58         if hot_url not in all_url_list and hot_title not in all_title_list:
     59             all_url_list.append(hot_url)
     60             all_title_list.append(hot_title)
     61             f.write(hot_title + '   ' + hot_url + '
    ')
     62         else:
     63             flag += 1
     64 
     65     # 热点视频
     66     video_list = soup.find_all(name='ul', attrs={'class': 'tuku_list'})
     67     video_a_list = video_list[0].find_all(name='a')
     68     for a in video_a_list:
     69         video_title = a.string
     70         video_url = a.attrs.get('href')
     71         # print(video_title, video_url)
     72         if video_url not in all_url_list and video_title not in all_title_list:
     73             all_url_list.append(video_url)
     74             all_title_list.append(video_title)
     75             f.write(video_title + '   ' + video_url + '
    ')
     76         else:
     77             flag += 1
     78 
     79     # 要闻
     80     yaowen_list = soup.find_all(name='ul', attrs={'class': 'yaowen_list'})
     81     yaowen_a_list = yaowen_list[0].find_all(name='a')
     82     for a in yaowen_a_list:
     83         yaowen_title = a.string
     84         yaowen_url = a.attrs.get('href')
     85         # print(yaowen_title, yaowen_url)
     86         if yaowen_url not in all_url_list and yaowen_title not in all_title_list:
     87             all_url_list.append(yaowen_url)
     88             all_title_list.append(yaowen_title)
     89             f.write(yaowen_title + '   ' + yaowen_url + '
    ')
     90         else:
     91             flag += 1
     92 
     93     f.close()
     94     print('第{0}个页面存储完成'.format(i), flag)
     95     # 一个页面中有44条新闻。如果改页面中的所有url都已经被存储过了,则可以大致认为已经获取到了所有的url
     96     # 实际少了十三条
     97     if flag == 44:
     98         return flag
     99     else:
    100         return
    101 
    102 
    103 if __name__ == '__main__':
    104     all_url_list = []
    105     all_title_list = []
    106     url = 'http://www.cymodel.net/deaafc/13143.html'
    107     all_url_list.append(url)
    108     i = 0
    109     while (True):
    110         # 如果想要把all_url_list里面的每个页面的url全部爬取一遍,则可以用这个条件作为循环结束
    111         # 把下面的内嵌if和函数里面的if else注释掉即可
    112         if( i < len(all_url_list) ):
    113             response = requests.get(url=all_url_list[i])
    114             flag = parse(response, all_url_list, all_title_list, i+1)
    115             i += 1
    116             if flag == 44:
    117                 print('已爬取大部分的url!!!!!')
    118                 break
    119         else:
    120             print('已爬取到所有的url!!!!!')
    121             break

     再写的时候,主要遇到了两个问题,一是如何实现去重,二是爬取到什么时候结束。

    第一个问题的解决办法是,先定义两个列表,用于存放每个页面的url和title,也就是all_url_liat和all_title_list,然后再每次存放url和title之前,先判断列表里面有没有这个url,如果没有,则进行存储,并添加到列表中。本来之定义了一个url的列表,但后来发现有的网页之间url不同,title相同,里面的内容也相同,所以又加了一个all_title_list。用这种方法实现去重的好处是比较简单,容易想到,但坏处是列表里面的元素过多,比较占内容,会有两个具有四百多个元素的列表,而且每次添加数据前,都要过一遍列表,判断要添加的url是否已经再列表中,这样就会导致程序运行较慢。

    第二个问题的解决办法一是根据每个页面未被存储的url数量判断,每个页面中共有44个新闻的链接,如果改页面中的44个链接都已经被存储过了,那么就认为已经获取到了大部分的url,第二种办法是把all_url_list中的每个url都爬取一下,这样能获取到所有的新闻链接,但耗时有点长,代码还需要优化。第一种办法的获取结果为416条,第二种办法获取到的是429条。

    *****************************不积跬步,无以至千里。 *****************************

  • 相关阅读:
    新浪微盘又是一个给力的产品啊,
    InfoQ: 百度数据库架构演变与设计
    列式数据库——Sybase IQ
    MapR初体验 淘宝共享数据平台 tbdata.org
    IBM正式发布新一代zEnterprise大型机(组图) 大型机,IBM,BladeCenter,美国,纽约 TechWeb News
    1TB is equal to the number of how many GB? 1PB equal to is equal to the number of TB? 1EB PB? | PCfault.com
    Cassandra vs HBase | WhyNosql
    The Hadoop Community Effect
    雅虎剥离开源软件平台 Hadoop ,与风投新建 Hortonworks 公司 品味雅虎
    RowOriented Database 、ColumnOriented Database 、KeyValue Store Database 、DocumentOriented Database
  • 原文地址:https://www.cnblogs.com/liangshian/p/11309035.html
Copyright © 2011-2022 走看看