python——爬虫&问题解决&思考(四)

  继续上一篇文章的内容,上一篇文章中已经将url管理器和下载器写好了。接下来就是url解析器,总的来说这个模块是几个模块中比较难的。因为通过下载器下载完页面之后,我们虽然得到了页面,但是这并不是我们想要的结果。而且由于页面的代码很多,我们很难去里面找到自己想要的数据。所幸,我们下载的是html页面,它是一种由多个多层次的节点组成的树型结构的文本文件。所以,相较于txt文件,我们更加容易定位到我们要找的数据块。现在我们要做的就是去原页面去分析一下,我们想要的数据到底在哪。

  打开百度百科pyton词条的页面,然后按F12调出开发者工具。通过使用工具,我们就能定位到页面的内容:

  这样我们就找到了我们想要的信息处在哪个标签里了。

 1 import bs4
 2 import re
 3 from urllib.parse import urljoin
 4 class HtmlParser(object):
 5     """docstring for HtmlParser"""
 6     def _get_new_urls(self, url, soup):
 7         new_urls = set()
 8         links = soup.find_all(‘a‘, href = re.compile(r‘/item/.‘))
 9         for link in links:
10             new_url = re.sub(r‘(/item/)(.*)‘, r‘\1%s‘ % link.getText(), link[‘href‘])
11             new_full_url = urljoin(url, new_url)
12             new_urls.add(new_full_url)
13         return new_urls
14
15     def _get_new_data(self, url, soup):
16         res_data = {}
17         #url
18         res_data[‘url‘] = url
19         #<dd class="lemmaWgt-lemmaTitle-title">
20         title_node = soup.find(‘dd‘, class_ = "lemmaWgt-lemmaTitle-title").find(‘h1‘)
21         res_data[‘title‘] = title_node.getText()
22         #<div class="lemma-summary" label-module="lemmaSummary">
23         summary_node = soup.find(‘div‘, class_ = "lemma-summary")
24         res_data[‘summary‘] = summary_node.getText()
25         return res_data
26
27     def parse(self, url, html_cont):
28         if url is None or html_cont is None:
29             return
30         soup = bs4.BeautifulSoup(html_cont, ‘lxml‘)
31         new_urls = self._get_new_urls(url, soup)
32         new_data = self._get_new_data(url, soup)
33         return new_urls, new_data

  解析器只有一个外部方法就是parse方法,

    a.首先它会接受url, html_cont两个参数,然后进行判断页面内容是否为空

    b.调用bs4模块的方法来解析网页内容,‘lxml‘为文档解析器,默认的为html.parser,bs官方推荐我们用lxml,那就听它的吧,谁让人家是官方呢。

    c.接下来就是调用两个内部函数来获取新的url列表和数据

    d.最后将url列表和数据返回

  这里有一些注意点

    1.bs的方法调用还有一个参数,from_encoding 这个和我在下载器那里的重复了,所以我就取消了,两个的功能是一样的。

    2.获取url列表的内部方法,需要用到正则表达式,这里我也是摸着石头过河,不是很会,中间也调试过许多次。

    3.数据是放在字典中的,这样可以通过key来增改删除数据。

最好,就直接数据输出了,这个比较简单,直接上代码。

  

 1 class HtmlOutputer(object):
 2     """docstring for HtmlOutputer"""
 3     def __init__(self):
 4         self.datas = []
 5     def collect_data(self, new_data):
 6         if new_data is None:
 7             return
 8         self.datas.append(new_data)
 9     def output_html(self):
10         fout = open(‘output1.html‘, ‘w‘, encoding = ‘utf-8‘)
11         fout.write(‘<html>‘)
12         fout.write(‘<head><meta charset="utf-8"></head>‘)
13         fout.write(‘<body>‘)
14         fout.write(‘<table>‘)
15         for data in self.datas:
16             fout.write(‘<tr>‘)
17             fout.write(‘<td>%s</td>‘ % data[‘url‘])
18             fout.write(‘<td>%s</td>‘ % data[‘title‘])
19             fout.write(‘<td>%s</td>‘ % data[‘summary‘])
20             fout.write(‘</tr>‘)
21         fout.write(‘</table>‘)
22         fout.write(‘</body>‘)
23         fout.write(‘</html>‘)
24         fout.close()

  这里也有两个注意点

    1.fout = open(‘output1.html‘, ‘w‘, encoding = ‘utf-8‘),这里的encoding参数一定要加,不然会报错,在windows平台,它默认是使用gbk编码来写文件的。

    2.fout.write(‘<head><meta charset="utf-8"></head>‘),这里的meta标签也要加上,因为要告诉浏览器使用什么编码来渲染页面,这里我一开始没加弄了很久,我打开页面的内容,发现里面是中文的,结果浏览器展示的就是乱码。总的来说,因为整个页面采集过程结果好几个模块,所以编码问题要非常小心,不然少不留神就会出错。

  最后总结,这段程序还有许多方面可以深入探讨:

  1.页面的数据量过小,我尝试了10000个页面的爬取。一旦数据量剧增之后,就会带来一下问题,第一是待爬取url和已爬取url就不能放在set集合中了,要么放到radi缓存服务器里,要么放到mysql数据库中

  2.第二,数据也是同样的,字典也满足不了了,需要专门的数据库来存放

  3.第三量上去之后,对爬取效率就有要求了,那么多线程就要加进来

  4.第四,一旦布置好任务,单台服务器的压力会过大,而且一旦宕机,风险很大,所以分布式的高可用架构也要跟上来

  5.一方面是页面的内容过于简单,都是静态页面,不涉及登录,也不涉及ajax动态获取

  6.这只是数据采集,后续还有建模,分析…………

综上所述,路还远的很呢,加油!

  

时间: 2024-10-29 08:56:56

python——爬虫&问题解决&思考(四)的相关文章

Python爬虫学习:四、headers和data的获取

之前在学习爬虫时,偶尔会遇到一些问题是有些网站需要登录后才能爬取内容,有的网站会识别是否是由浏览器发出的请求. 一.headers的获取 就以博客园的首页为例:http://www.cnblogs.com/ 打开网页,按下F12键,如下图所示: 点击下方标签中的Network,如下: 之后再点击下图所示位置: 找到红色下划线位置所示的标签并点击,在右边的显示内容中可以查看到所需要的headers信息. 一般只需要添加User-Agent这一信息就足够了,headers同样也是字典类型: user

Python 爬虫入门(四)—— 验证码上篇(主要讲述验证码验证流程,不含破解验证码)

本篇主要讲述验证码的验证流程,包括如何验证码的实现.如何获取验证码.识别验证码(这篇是人来识别,机器识别放在下篇).发送验证码.同样以一个例子来说明.目标网址 http://icp.alexa.cn/index.php(查询域名备案信息) 1.验证码的实现: 简单的说,验证码就是一张图片,图片上有字符串.网站是如何实现的呢?有WEB基础的人可能会知道,每个浏览器基本都有cookie,作为这次回话的唯一标示.每次访问网站,浏览器都会把这个cookie发送给服务器.验证码就是和这个cookie绑定到

python爬虫学习第四章

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption

python爬虫入门(四)利用多线程爬虫

多线程爬虫 先回顾前面学过的一些知识 1.一个cpu一次只能执行一个任务,多个cpu同时可以执行多个任务2.一个cpu一次只能执行一个进程,其它进程处于非运行状态3.进程里包含的执行单元叫线程,一个进程可以包含多个线程4.一个进程的内存空间是共享的,每个进程里的线程都可以使用这个共享空间5.一个线程在使用这个共享空间的时候,其它的线程必须等待(阻塞状态)6.互斥锁作用就是防止多个线程同时使用这块内存空间,先使用的线程会将空间上锁,其它的线程处于等待状态.等锁开了才能进7.进程:表示程序的一次执行

Python爬虫(二十四)_selenium案例:执行javascript脚本

本章叫介绍如何使用selenium在浏览器中使用js脚本,更多内容请参考:Python学习指南 隐藏百度图片 #-*- coding:utf-8 -*- #本篇将模拟执行javascript语句 from selenium import webdriver from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.get('https://www.baidu.com/') #给搜索输入框标

python 爬虫实例(四)

环境: OS:Window10 python:3.7 爬取链家地产上面的数据,两个画面上的数据的爬取 效果,下面的两个网页中的数据取出来 代码 import datetime import threading import requests from bs4 import BeautifulSoup class LianjiaHouseInfo: ''' 初期化变量的值 ''' def __init__(self): # 定义自己要爬取的URL self.url = "https://dl.li

python爬虫---实现项目(四) 用BeautifulSoup分析新浪新闻数据

这次只演示了,如何在真实项目内用到BeautifulSoup库来解析网页,而新浪的新闻是ajax加载过来的数据,在这里我们只演示解析部分数据(具体反扒机制没做分析). 代码地址:https://gitee.com/dwyui/BeautifulSoup_xinlang.git. 关于的爬虫的博客已经越来越多,使用到的技术也越来越多,后期我还会持续写下去,大概从几个角度去写,多线程爬取(提高效率),如何更好的做到爬取数据(破解反扒). 用redis管理多线程和代理IP,后期也会做一段关于非关系型数

小白如何入门 Python 爬虫?

本文针对初学者,我会用最简单的案例告诉你如何入门python爬虫! 想要入门Python 爬虫首先需要解决四个问题 熟悉python编程 了解HTML 了解网络爬虫的基本原理 学习使用python爬虫库 一.你应该知道什么是爬虫? 网络爬虫,其实叫作网络数据采集更容易理解. 就是通过编程向网络服务器请求数据(HTML表单),然后解析HTML,提取出自己想要的数据. 归纳为四大步: 根据url获取HTML数据 解析HTML,获取目标信息 存储数据 重复第一步 这会涉及到数据库.网络服务器.HTTP

Python爬虫利器四之PhantomJS的用法

前言 大家有没有发现之前我们写的爬虫都有一个共性,就是只能爬取单纯的html代码,如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没天理了.所以,我们需要有一些好用的工具来帮助我们像浏览器一样渲染JS处理的页面. 其中有一个比较常用的工具,那就是 PhantomJS Full web stack No browser required PhantomJS is a headless WebKit scriptable with a Ja