在这个数据为王的时代,掌握一手好的模型炼丹技巧还远远不够,有时候就是那么一小撮数据,就会对模型性能产生至关重要的影响。虽说大一点的公司一般都有专门负责爬虫的同学,但求人不如求己,每一位炼丹师都应该掌握一些基本的爬虫知识。本篇文章就和大家聊一聊如何通过爬虫,获得自己想要的数据。
今天先来讲讲相对简单的静态页面爬取,不同于动态页面,静态页面是存在于服务器(访问时没有查数据库的过程),不含程序,不可交互。简单来说,我们想要爬取的内容都可从网页源码直接解析得到。在爬取这类网页时,一般分为三步:
- 模拟浏览器的真实请求,构造请求消息
- 发送人为构造的请求消息,获取网站响应的网页源代码
- 对网站源代码进行解析、清洗,找到自己想要的数据并加以保存
对应上面的3步,每一步都有很多可直接使用的Python库。这里我们使用requests库构造请求消息并从网站获取源码,使用BeautifulSoup解析网页源码,使用xlwt将清洗后的数据保存为.xls格式的文件输出。下面举个栗子:
以爬取网站融360为例,该网站的资讯新闻均为静态页面,且亲测几乎没有任何反爬机制,非常适合拿来练手。网站的资讯文章列表如下:
该网站共有44713条资讯文章,共计4472页,通过点击下一页查看URL的变化,发现页码刚好与URL中的最后一位数字对应。
下面直接上代码
import requests
from bs4 import BeautifulSoup
import xlwt
import time
def spider(page):
url = 'https://www.rong360.com/gl/daikuangonglue/list_1_{0}.html'.format(str(page))
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36'}
response = requests.get(url, headers=headers).content
soup = BeautifulSoup(response, 'lxml')
list = soup.find_all('h3')
global num
for item in list:
data_url = 'https://www.rong360.com' + item.a['href']
data = requests.get(data_url, headers=headers).content
data_soup = BeautifulSoup(data, 'lxml')
try:
tmp = data_soup.find_all('div', class_='act-content')[0]
title = tmp.h1.text
sentence = tmp.find_all('p')
result = []
for s in sentence:
result.extend(s.text.strip().replace('\n', ''))
context = ''.join(result)
num += 1
print("第{0}篇文章已爬取完成".format(num))
sheet.write(num, 0, title)
sheet.write(num, 1, context)
except:
pass
if __name__ == '__main__':
book = xlwt.Workbook(encoding='utf-8')
sheet = book.add_sheet('金融新闻数据')
sheet.write(0, 0, '文章标题')
sheet.write(0, 1, '文章内容')
num = 0
for i in range(1, 4472):
spider(i)
time.sleep(3)
print("共爬取{0}篇文章".format(num))
book.save(u"rong360爬虫结果.xls")
分析上面的代码,首先借助User-Agent将我们的请求消息伪装成浏览器,然后requests.get()获取每一页的源码,并对其进行解析。
url = 'https://www.rong360.com/gl/daikuangonglue/list_1_{0}.html'.format(str(page))
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36'}
response = requests.get(url, headers=headers).content
soup = BeautifulSoup(response, 'lxml')
list = soup.find_all('h3')
我们把soup 打印出来如下,发现每一个页码面其实只展现了每篇文章的标题以及部分摘要,真正的文章链接存储于标签的"href"中,如下所示:
<h3><a class="title" href="/gl/2019/12/18/181204.html"><b>小心了!这些人申请房贷,会被银行拒绝!</b></a></h3>
<span>2020/10/28</span>
<p> 买房申请贷款,有些人能够顺利批贷,而有些人却因为某些不可抗拒的原因被银行拒贷,梦想很丰满,但现实却很骨感,这些原因成为他们 买房贷款 路上...</p>
</li><li>
<h3><a class="title" href="/gl/2019/12/31/181321.html"><b>重磅!超20万亿存量房贷迎重大调整 对老用户影响几何?</b></a></h3>
<span>2020/10/28</span>
<p> 2019年最后一个周末,存量浮动利率贷款定价转换方案正式出台,是央行继8月LPR新机制改革后的又一重大举措。银行前期准备工作繁杂 但来年整体收益下...</p>
</li><li>
<h3><a class="title" href="/gl/2020/10/20/182627.html"><b>全国房贷利率终止“九连降”,拐点已现?</b></a></h3>
借助soup.find_all(‘h3’)我们找到所有h3,对结果进行遍历进而找到每篇文章的真实URL,注意得到的URL是相对路径,将其转换成绝对路径后重新请求并解析返回结果。
for item in list:
data_url = 'https://www.rong360.com' + item.a['href']
data = requests.get(data_url, headers=headers).content
data_soup = BeautifulSoup(data, 'lxml')
我们把每篇文章的响应结果data_soup 打印出来看,终于在
<div class="act-content">
<h1>小心了!这些人申请房贷,会被银行拒绝!</h1>
<div class="act-info">
<span>时间:2019-12-18
来源:融360
作者:融360
</span>
</div>
<div>
<p>
买房申请贷款,有些人能够顺利批贷,而有些人却因为某些不可抗拒的原因被银行拒贷,梦想很丰满,但现实却很骨感,这些原因成为他们<a href="http://www.rong360.com/fd/" target="_blank"></a><a href="http://www.rong360.com/fd/" target="_blank"></a><a href="http://www.rong360.com/fd/" target="_blank">买房贷款</a>路上的“硬伤”,想补救都难,到底什么样的理由让人连房奴都做不成呢?</p>
<p>
<strong>1、征信不良</strong></p>
<p>
个人征信是银行考量借款人申贷条件的重要标准之一,信用不好的借款人很容易被银行拒贷,这里说的信用不良,主要包括信用卡逾期、贷款逾期,为他人做担保,对方贷款逾期不还等都会给申请人形成信用污点,即使是换几家银行咨询也是无济于事。</p>
<p>
接下来就是对文章标题以及主体内容进行解析,并利用xlwt库对每篇文章进行保存,代码如下:
try:
tmp = data_soup.find_all('div', class_='act-content')[0]
title = tmp.h1.text
sentence = tmp.find_all('p')
result = []
for s in sentence:
result.extend(s.text.strip().replace('\n', ''))
context = ''.join(result)
num += 1
print("第{0}篇文章已爬取完成".format(num))
sheet.write(num, 0, title)
sheet.write(num, 1, context)
except:
pass
至此大功告成,我们看一下最终结果:
此次共爬取44578篇文章,耗时大约7小时。另外,大家如果嫌速度慢可以自己写一个多线程模块,加快爬取,对于涉及的BeautifulSoup用法文中没有赘述,感兴趣的同学可以查阅官方文档,里面介绍的非常详细,完整代码及爬取到的数据我也放在github上了,连接: https://github.com/NLPliands/spider-examples
本文同步于微信公众号“NLP炼丹师”,感兴趣的同学可扫码关注,获取更多内容。