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

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

 import requests
from bs4 import BeautifulSoup # response请求页面的响应,all_url_lis用于存放所有页面的utl,all_title_list用于存放所有页面的title,
# i用来显示当前爬取到第几个页面 def parse(response, all_url_list, all_title_list, i):
html = response.content # 先获取二进制形式的内容,下面再进行转换,否则会出现中文乱码
html = str(html, encoding='utf-8')
soup = BeautifulSoup(html, 'lxml') # 利用Beautifulsoup解析库
f = open('title_and_url.txt', 'a', encoding='utf-8') # 打开文件,存储所有页面的title和url # 获取正文
# content = soup.find(name='div', attrs={'class': 'main_article'})
# p_list = content.find_all(name='p')
# for p in p_list:
# print(p.string) flag = 0 # 用来标志当前页面的url有多少已经存储过了,后面可以作为结束循环的条件 # 获取下方社会新闻
Sociology_list = soup.find_all(name='div', attrs={'class': 'r'})
sociology_a_list = Sociology_list[0].find_all(name='a')
for a in sociology_a_list:
sociology_title = a.string
sociology_url = a.attrs.get('href')
# print(sociology_title, sociology_url)
# 判断列表中是否已经存在这个页面的url或title,实现去重
if sociology_url not in all_url_list and sociology_title not in all_title_list:
all_url_list.append(sociology_url)
all_title_list.append(sociology_title)
f.write(sociology_title + ' ' + sociology_url + '\n')
else:
flag += 1 # 获取排行榜
Ranking_list = soup.find_all(name='ul', attrs={'class': 'tt', 'id': 'tt'})
rank_a_list = Ranking_list[0].find_all(name='a')
for a in rank_a_list:
rank_title = a.string
rank_url = a.attrs.get('href')
# print(rank_title, rank_url)
if rank_url not in all_url_list and rank_title not in all_title_list:
all_url_list.append(rank_url)
all_title_list.append(rank_title)
f.write(rank_title + ' ' + rank_url + '\n')
else:
flag += 1 # 热点推荐
hot_list = soup.find_all(name='ul', attrs={'class': 'ducheng_list'})
hot_a_list = hot_list[0].find_all(name='a')
for a in hot_a_list:
hot_title = a.string
hot_url = a.attrs.get('href')
# print(hot_title, hot_url)
if hot_url not in all_url_list and hot_title not in all_title_list:
all_url_list.append(hot_url)
all_title_list.append(hot_title)
f.write(hot_title + ' ' + hot_url + '\n')
else:
flag += 1 # 热点视频
video_list = soup.find_all(name='ul', attrs={'class': 'tuku_list'})
video_a_list = video_list[0].find_all(name='a')
for a in video_a_list:
video_title = a.string
video_url = a.attrs.get('href')
# print(video_title, video_url)
if video_url not in all_url_list and video_title not in all_title_list:
all_url_list.append(video_url)
all_title_list.append(video_title)
f.write(video_title + ' ' + video_url + '\n')
else:
flag += 1 # 要闻
yaowen_list = soup.find_all(name='ul', attrs={'class': 'yaowen_list'})
yaowen_a_list = yaowen_list[0].find_all(name='a')
for a in yaowen_a_list:
yaowen_title = a.string
yaowen_url = a.attrs.get('href')
# print(yaowen_title, yaowen_url)
if yaowen_url not in all_url_list and yaowen_title not in all_title_list:
all_url_list.append(yaowen_url)
all_title_list.append(yaowen_title)
f.write(yaowen_title + ' ' + yaowen_url + '\n')
else:
flag += 1 f.close()
print('第{0}个页面存储完成'.format(i), flag)
# 一个页面中有44条新闻。如果改页面中的所有url都已经被存储过了,则可以大致认为已经获取到了所有的url
# 实际少了十三条
if flag == 44:
return flag
else:
return if __name__ == '__main__':
all_url_list = []
all_title_list = []
url = 'http://www.cymodel.net/deaafc/13143.html'
all_url_list.append(url)
i = 0
while (True):
# 如果想要把all_url_list里面的每个页面的url全部爬取一遍,则可以用这个条件作为循环结束
# 把下面的内嵌if和函数里面的if else注释掉即可
if( i < len(all_url_list) ):
response = requests.get(url=all_url_list[i])
flag = parse(response, all_url_list, all_title_list, i+1)
i += 1
if flag == 44:
print('已爬取大部分的url!!!!!')
break
else:
print('已爬取到所有的url!!!!!')
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条。

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

python爬虫之深度爬取实例的更多相关文章

  1. Python爬虫教程-17-ajax爬取实例(豆瓣电影)

    Python爬虫教程-17-ajax爬取实例(豆瓣电影) ajax: 简单的说,就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互 对于ajax: ...

  2. 【转载】教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

    原文:教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神 本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http:/ ...

  3. python爬虫-基础入门-爬取整个网站《3》

    python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...

  4. python爬虫-基础入门-爬取整个网站《2》

    python爬虫-基础入门-爬取整个网站<2> 描述: 开场白已在<python爬虫-基础入门-爬取整个网站<1>>中描述过了,这里不在描述,只附上 python3 ...

  5. python爬虫-基础入门-爬取整个网站《1》

    python爬虫-基础入门-爬取整个网站<1> 描述: 使用环境:python2.7.15 ,开发工具:pycharm,现爬取一个网站页面(http://www.baidu.com)所有数 ...

  6. Python 爬虫入门之爬取妹子图

    Python 爬虫入门之爬取妹子图 来源:李英杰  链接: https://segmentfault.com/a/1190000015798452 听说你写代码没动力?本文就给你动力,爬取妹子图.如果 ...

  7. Python爬虫实战之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 对百度贴吧的任意帖子进行抓取 指定是否只抓取楼主发帖 ...

  8. python 爬虫 requests+BeautifulSoup 爬取巨潮资讯公司概况代码实例

    第一次写一个算是比较完整的爬虫,自我感觉极差啊,代码low,效率差,也没有保存到本地文件或者数据库,强行使用了一波多线程导致数据顺序发生了变化... 贴在这里,引以为戒吧. # -*- coding: ...

  9. 教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

    本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http://www.xiaohuar.com/,让你体验爬取校花的成就感. Scr ...

随机推荐

  1. CodeForces - 103B(思维+dfs找环)

    题意 https://vjudge.net/problem/CodeForces-103B 很久很久以前的一天,一位美男子来到海边,海上狂风大作.美男子希望在海中找到美人鱼 ,但是很不幸他只找到了章鱼 ...

  2. 201871010114-李岩松《面向对象程序设计(java)》第十四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  3. mysql索引类型:FULLTEXT、NORMAL、SPATIAL、UNIQUE的详细介绍(转)

    Normal 普通索引 表示普通索引,大多数情况下都可以使用 Unique 唯一索引 表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique 约束唯一标识 ...

  4. verilog问题二三

    assign语句叫连续赋值语句?为什么要叫连续,是由于等式右边是顺序执行的还是因为在执行赋值的过程中,赋值的先后顺序(实际上或者概念上)是有顺序的? 同步(复位)与异步(复位)的具体内涵:异步信号定义 ...

  5. LeetCode解题笔记 - 2. Add Two Numbers

    2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. ...

  6. Go 字节 (byte) & 文字符号 (rune)

    byte 通过 byte 定义一个字节,字节必须使用单引号包起来,直接打印字节输出的是 ascii 码,需要通过格式化输出 byte 是 uint8 的别称,使用 byte 主要是为了区分字节和无符号 ...

  7. 设计模式-State(行为模式)-很好的实现了对象的状态逻辑与动作实现的分类,状态逻辑在State的派生类实现,动作可以放在Context类中实现。

    以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Context.h #pragma once class State; class Context { public: C ...

  8. WPF 精修篇 page

    原文:WPF 精修篇 page 前言 前段时间看UML 大象 这本书 虽然马上看到了精华片 最后还是暂时暂停 因为这本书 很好 但是暂时对现在的我来说 有点超前 很多东西理解起来还是很难 但是 这本书 ...

  9. hdu6464 线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=6464 题意 一个空序列,q次操作,一种是往序列后插入x个y,另一种是查询序列中第x小到第y小的数字之和 题解 线 ...

  10. Global AI Bootcamp 2019 宁波站活动总结

    2019年12月14日,由微软MVP技术社区发起的Global AI Bootcamp 2019盛会在全球60多个国家130个城市点燃.在大中华区,本次活动由全国众多Azure专家及微软MVP技术社区 ...