python爬虫之深度爬取实例
写了一个之前没完成的项目,代码优化不够,速度有点慢,应该也有错误的地方,望大佬看了之后能给点建议。。。。。。。。。
这是开始的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爬虫之深度爬取实例的更多相关文章
- Python爬虫教程-17-ajax爬取实例(豆瓣电影)
Python爬虫教程-17-ajax爬取实例(豆瓣电影) ajax: 简单的说,就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互 对于ajax: ...
- 【转载】教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神
原文:教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神 本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http:/ ...
- python爬虫-基础入门-爬取整个网站《3》
python爬虫-基础入门-爬取整个网站<3> 描述: 前两章粗略的讲述了python2.python3爬取整个网站,这章节简单的记录一下python2.python3的区别 python ...
- python爬虫-基础入门-爬取整个网站《2》
python爬虫-基础入门-爬取整个网站<2> 描述: 开场白已在<python爬虫-基础入门-爬取整个网站<1>>中描述过了,这里不在描述,只附上 python3 ...
- python爬虫-基础入门-爬取整个网站《1》
python爬虫-基础入门-爬取整个网站<1> 描述: 使用环境:python2.7.15 ,开发工具:pycharm,现爬取一个网站页面(http://www.baidu.com)所有数 ...
- Python 爬虫入门之爬取妹子图
Python 爬虫入门之爬取妹子图 来源:李英杰 链接: https://segmentfault.com/a/1190000015798452 听说你写代码没动力?本文就给你动力,爬取妹子图.如果 ...
- Python爬虫实战之爬取百度贴吧帖子
大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 对百度贴吧的任意帖子进行抓取 指定是否只抓取楼主发帖 ...
- python 爬虫 requests+BeautifulSoup 爬取巨潮资讯公司概况代码实例
第一次写一个算是比较完整的爬虫,自我感觉极差啊,代码low,效率差,也没有保存到本地文件或者数据库,强行使用了一波多线程导致数据顺序发生了变化... 贴在这里,引以为戒吧. # -*- coding: ...
- 教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神
本博文将带领你从入门到精通爬虫框架Scrapy,最终具备爬取任何网页的数据的能力.本文以校花网为例进行爬取,校花网:http://www.xiaohuar.com/,让你体验爬取校花的成就感. Scr ...
随机推荐
- 如果不配https访问权限,可以用 .htaccess 搞定
.htaccess 此文件存放在,网站程序根目录下# 只允许通过域名形式访问 RewriteEngine On RewriteBase / rewritecond %{http_host} !^www ...
- leetcode 752. 打开转盘锁
地址 https://leetcode-cn.com/problems/open-the-lock/ 你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字: '0', '1', '2', '3', ...
- WPF 快捷键
原文:WPF 快捷键 <p><pre name="code" class="csharp"> 前台 <Window.Resourc ...
- MySQL数据库实战之优酷
目录 一.项目总结三步骤 二.项目需求分析 三.搭建框架 四.ORM框架分析 五.数据库设计 六.项目中各个功能模块分析 七.项目中遇到的问题及怎么解决的 八.客户端代码框架 8.1 conf 8.1 ...
- nodejs的require是如何执行的
通常,在Node.js里导入是通过 require函数调用进行的. Node.js会根据 require的是相对路径还是非相对路径做出不同的行为. 相对路径 相对路径很简单. 例如,假设有一个文件路径 ...
- 使用layer.msg 时间设置不起作用
前几天使用layer.msg设置时间后发现不起作用,这里记录一下. 开始出错误的代码: 后面查看文档后得知调用layer.msg后如果有后续操作需要写在function()中: //eg1 layer ...
- C语言程序设计100例之(2):一元二次方程
例2 一元二次方程 [题目描述] 输入系数a.b和c,求方程ax2+bx+c=0的根. [输入格式] 输入数据有多组.每组数据包括三个系数a,b,c.当a=0时,输入数据结束. [输出格式] 输出 ...
- linux学习之Ubuntu
查看自己的ubuntu版本,输入以下命令(我的都是在root用户下的,在普通用户要使用sudo)第一行的lsb是因为没有安装LSB,安装之后就不会出现这个东西.LSB(Linux Standards ...
- 现代C++实现多种print
目录 Print Version1 Print Version2 Print Version3 Print Version4 容器的Print tuple容器的print 结语 学习C++的朋友会遇到 ...
- EF-入门操作
EntityFramework Core 理解 DbContext :数据库 DbSet: 数据库表 Model : 数据行 IQueryable<Model> 查询结果集合 Lamada ...