今天,根据网页的结构,尝试了下如何抓取煎蛋首页上的文章。目标很简单:
根据首页上面的文章链接,载入文章,而后将文章的标题和正文(不带图片)抓取下来。
抓取首页上面文章的链接,标题,作者和所属标签。
按标题将文章写入一个
.txt
格式的文件将首页上抓取的内容整合起来,制作成格式如下的
Markdown
简介。
首页的简介格式如下:
**文章标题**:鲸鱼有鲸语,鲸语有口音
**文章链接**:[http://jandan.net/2016/02/18/caribbean-whales.html](http://jandan.net/2016/02/18/caribbean-whales.html)
**译者**:Cedric
**标签**:走进科学
...
如此反复即可。这里要说明下,由于煎蛋首页和余下页码的网页结构不同,我没有再写余下页面的简介。如果有人有兴趣的话,可以编写则个~下面,我会说明在编写爬虫过程中的所思所想。
1. 爬虫前的准备
我这里使用了Python中的以下模块:
beautifulsoup
:第三方模块,用于解析网页内容。requests
:第三方模块,用于获取网页内容。re
:内置模块,用于编写正则表达式codecs
:内置模块,用于操作文件
这便是全部准备了。在这里要多嘴一句,包括re
模块在内都存在替代品,如果需要可以根据自己的喜好来选择。
2. 分析程序逻辑
在编写代码之前,要分析如何抓取并处理网页。以抓取一篇文章鲸鱼有鲸语,鲸语有口音为例。我们要实现:
下载网页,获取数据——源代码或者
json
数据解析数据,从数据中抽出我们需要的内容——这里是文章标题和文章内容(只有文字)
整理数据,将解析好的数据写入文件中。
这样,可以根据实现的内容,将代码分为三个部分,用函数来整合:
download_page(url)
:接受一个URL(通常是网址),下载网页,而后获取数据(当然,不止下载网页而已,还有很多内容,但对于现在来说,这么讲就好)parse_article(data)
:接受上面的函数返回的data
,并解析为我们需要的内容write_article(title, content)
:接受上面的函数返回的标题和文章内容,并写入文件中。
这三个部分中,现在我感觉最难的是其中的parse_article(data)
。当然,一部分是因为我的经验不足,经常要花很长时间才找到需要的内容。这里,推荐读者在浏览器中使用右键——查找元素
来辅助解析网页。
当明白怎么爬取一篇文章的时候,爬取其他内容就是一些细节上的事情了。细节上的内容可以通过模块的文档来获取。我提到的两个第三方模块的中文资料都比较丰富(百度一下即可),所以不再赘述。这里只说明几个需要注意下的细节:
在发送请求的时候,网页可能会通过检查头信息中的
User-Agent
来判断是否是一个人浏览网页。最简单的解决问题的方法就是自己写一个头信息,伪装成一个人。-
如果抓取的频率过快,可能会被服务器拒绝访问,如果IP被封了就完了。这里有两个解决问题的思路:
使用IP代理,轮换IP访问网页
设置一个简单的爬虫测试服务器可以接受的访问频率,从慢而快的访问网页。(就是看服务器的忍受程度是多少)
网页上通常不止有一个地方包含了我们所需的内容(比如有两个块可以实现下一页的功能),所以,一个块难解析可以使用另一个块,变通下嘛~
3. 爬虫实例
这里以抓取一篇文章鲸鱼有鲸语,鲸语有口音为例。刚才提到了,要实现三个函数:
download_page(url)
parse_article(data)
write_article(title, content)
3.1 下载数据
首先是第一个函数download_page(url)
。由于内容单一,所以实现比较简单(要注意的是,这里需要准备一些防反爬虫的措施)。下面将展示如何伪装成一个浏览器下载网页或者其中的数据:
def download_page(url):
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) '
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36'
}
data = requests.get(url, headers=headers).content
return data
我们这里伪装了一个火狐浏览器。这个信息不需要你输入或者从这里复制,如果需要的话,可以在浏览器中右键——查看元素——网络
而后就可以查看消息头并伪装成你自己的浏览器了。我们这里使用的HTTP请求中的get
方法,如果有看过之前的内容(指HTTP权威指南的一部分),就可以明白这里是什么意思啦~
3.2 解析数据
下面是第二个函数parse_article(data)
,内容比较复杂,而且是根据我们要爬取的文章页面制定的。我们首先放到文章的主体上,右键——查看元素
,可以看到主体的部分结构是这样的:
嗯,可以明白(如果不明白的话,请自己补习HTML的基础知识。这部分在Segmantfault里面搜集即可)文章的主体部分在<div class="post f">
中。其中,标题在其中的<h1>
标签的文本内部,而正文则是其中的<p>
标签的内容。
据此,我们可以使用beatifulsoup
来实现我们的第二个函数:
def parse_article(html):
soup = BeautifulSoup(html, 'html.parser')
# 从上面的数据获取html文档并解析,这里使用的是Python自带的HTML解释器
article = soup.find('div', attrs={'class': 'post f'})
# 缩小HTML文档的解析范围,限定在文章主体内部。
title = article.find('h1').getText()
# 获取文章主体内部的<h1>标签内的文本,可以发现这就是标题内容。
paras = []
# 创建一个列表,以段落的形式,向里面填充文本。
for paragraph in article.find_all('p'):
p_content = paragraph.getText()
# 获取<p>标签内的文本,这里就是段落文本内容。
paras.append(p_content)
return title, paras
# 返回标题和参数,用于写入文件。
3.3 整理数据
获取我们需要的所有数据(标题和内容)以后,需要将其写入文件中。我们首先需要拼接一个文件名,创建并打开文件。这里要注意参数wb
。在Python3.X中,b
参数是自动添加的(如果没有写则会填上去,有的话就不会自己填上去);但是在Python2.X中不是这样,所以最好填上去,避免换了版本以后出现一些奇怪的Bug。当然,不换也行~
def get_article(title, url):
file_name = title + '.txt'
# 拼接文件名
with codecs.open(file_name, 'wb', encoding='utf-8') as fp:
html = download_page(url)
# 调用第一个函数获取数据
title2, text = parse_article(html)
# 调用第二个函数获取数据
fp.write('\t%s\t\r\n' % title2)
for p in text:
fp.write('\t%s\r\n' % p)
# 将获取的数据写入文件。
print('文章读取完毕!')
return 'OK'
最后,还要再编写一个if
语句,判断是运行还是导入。运行文件的时候,可以通过调用第三个函数来实现我们的目的。
if __name__ == '__main__':
url = 'http://jandan.net/2016/02/18/caribbean-whales.html'
get_article(url)
4. 文章结束前的一些话
嗯,本文到这里就结束了。下面还有抓取简单首页文章的爬虫。不过爬取的过程也是上面的几步,如果看懂的话,就可以编写出来。看不懂的话……嗯,其实我只是因为开心想炫耀一下,哈哈哈哈来打我啊~~
我是胡一波,集帅气与智慧于一身的美男子,每天都被自己帅醒。如果各位发现这些代码有问题的话,请跟我说,我会尽快回复并发送一块钱!这些钱可以指定给任意人或者机构(比如慈善组织和开源项目),就酱~