现在Python非常的热门,之前在一个公众号的启发下,萌发了学习爬虫的兴趣,之前自学过Python的一点基础,所以经过几天的折腾终于弄出了一个小小的案例—用BeautifulSoup爬取了自己博客一些信息,有点小兴奋,想分享一下内心的小成就,希望大神不要笑话
1.首先需要安装好_BeautifulSoup_
如果你还没有安装好BeautifulSoup,参考这个博客点击跳转
2.观察信息位置
假设你已经安装好了**beautifulsoup
** (反正我也看不见,就当你安装好了呗)
现在可以打开我们需要抓取数据的网址了,由于我是抓取我自己博客的信息,所以直接通过F12
,浏览器的查看功能,找到需要抓的信息是在哪里
通过观察,可以发现我们需要找的标题是在<span class="link_title">
下的的<a>
标签中,因此我们可以通过这个来快速查找 (注意:这种办法在确定唯一性时候可以使用,否则的话,会抓到你不想要的结果
)
3.获取浏览器的Header信息
通过图片介绍的方法复制第4步的**User-Agent
的信息,为什么要用到User-Agent
**呢,因为CSDN为了阻止别人恶意采集信息采取了反爬虫的设置
4.进入正题
下面直接上代码了
import urllib.request
from bs4 import BeautifulSoup
#如果没有安装好BeautifulSoup,这里是会报错的
#自定义一个函数拿到博客的链接
def getUrl (url):
#定义一个headers,存储刚才复制下来的报头,模拟成浏览器
headers = ('User-Agent',
"Mozilla/5.0 (Windows NT 10.0; Win32; x32; rv:48.0) Gucko/20130101 Firefox/58.0")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
# 将opener安装为全局
urllib.request.install_opener(opener)
html = urllib.request.urlopen(url).read().decode('utf-8', 'ignore')
bs = BeautifulSoup(html,'html.parser')
# 用beautifulsoup的select,找到所有的<a>标签
links = bs.select('.link_title > a')
return links
# 要爬取的网页链接
url = 'https://blog.csdn.net/stormdony'
# 获取对应网页的链接地址
linklist = getUrl(url)
# 定义一个列表texts存储文章的标题
texts = []
# 定义一个列表links存储文章的链接
links = []
# 遍历linkllist,存储标题和链接
for link in linklist:
texts.append(link.text.strip())
links.append(link.get('href'))
# 通过zip,将信息输出到控制台
for text, link in zip(texts, links):
data = {'tittle': text, 'link': link}
print(data)
5.验收成果
经过几天的折腾终于搞出的一点小成就,不喜勿喷 _
6.再次更新
================ 再次更新于2018/12/20 ======================
CSDN最近的页面改版了,所以上面的代码已经不适用了。
选择器的路径需要改成下图中圈起来的才行。
另外还需要去除原创或者转载的表示。
通过手动改变链接,让链接的页数超出总博文的页数,对比发现如果是非法输入超过总页数的链接的话,页面底部是没有分页的功能的,所以可以添加一个for循环,通过循环足够多的次数,当没有分页时,就退出整个程序,这样就不至于一直循环。
代码:
import urllib.request
from bs4 import BeautifulSoup
#如果没有安装好BeautifulSoup,这里是会报错的
#自定义一个函数拿到博客的链接
def getUrl (url):
#定义一个headers,存储刚才复制下来的报头,模拟成浏览器
headers = ('User-Agent',
"Mozilla/5.0 (Windows NT 10.0; Win32; x32; rv:48.0) Gucko/20130101 Firefox/58.0")
opener = urllib.request.build_opener()
opener.addheaders = [headers]
# 将opener安装为全局
urllib.request.install_opener(opener)
html = urllib.request.urlopen(url).read().decode('utf-8', 'ignore')
# print(html)
bs = BeautifulSoup(html,'lxml')
# 用beautifulsoup的select,找到所有的<a>标签
pages = bs.select(".pagination-box")
if pages:
# 判断是否包含下一页的选项
# 用beautifulsoup的select,找到所有的<a>标签
links = bs.select('.article-list > .article-item-box > h4 > a')
return links
else:
# 结束整个程序
sys.exit()
import sys
if __name__ == '__main__':
# 要爬取的网页链接 ,循环足够多的页数,所以填了1000000
for i in range(1,1000000):
url = 'https://blog.csdn.net/stormdony/article/list/{}'.format(i)
# 获取对应网页的链接地址
linklist = getUrl(url)
# 定义一个列表texts存储文章的标题
texts = []
# 定义一个列表links存储文章的链接
links = []
# 遍历linkllist,存储标题和链接
for link in linklist:
texts.append(link.text.strip())
links.append(link.get('href'))
# 通过zip,将信息输出到控制台
for text, link in zip(texts, links):
text = text.strip().replace("原 \n ", "")
text = text.strip().replace("转 \n ", "")
data = {'tittle': text, 'link': link}
print(data)
由于是之前写的博客,当时没有学到很多。现在,建议不要使用urllib.request
了,强烈推荐使用requests
库。
此外,感谢底下留言通知我的博友!!
7.再再次更新
=========== 再再此更新于2018/12/21 ========
更新功能:可以分类爬取原创和转载两类文章;
import requests
from bs4 import BeautifulSoup
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36',
}
def getOriginalArticle(username):
'''获取原创文章'''
for i in range(1,1000000):
url = 'https://blog.csdn.net/{}/article/list/{}?t=1'.format(username,i)
web_data = requests.get(url, headers=header)
soup = BeautifulSoup(web_data.content, 'lxml')
pages = soup.select(".pagination-box")
links = soup.select('.article-list > .article-item-box > h4 > a')[1:]
readnum = soup.select('.read-num')
if pages:
# 判断是否包含下一页的选项
# 用beautifulsoup的select,找到所有的<a>标签
printOriginalData(links,readnum,'原 \n ')
else:
# 结束循环
break
def getTranshipmentArticle(username):
'''获取转载文章'''
for i in range(1,1000000):
url = 'https://blog.csdn.net/{}/article/list/{}?t=2'.format(username,i)
web_data = requests.get(url,headers=header)
soup = BeautifulSoup(web_data.content, 'lxml')
pages = soup.select(".pagination-box")
links = soup.select('.article-list > .article-item-box > h4 > a')[1:]
readnum = soup.select('.read-num')
if pages:
printTranshipmentData(links,readnum,'转 \n ')
else:
# 这里可能会有问题,因为我的转载文章还不够分页的数量,所以需要添加多一条printTranshipmentData()
printTranshipmentData(links, readnum, '转 \n ')
# 结束循环
break
def printTranshipmentData(links,readnum,stripText):
for link in links:
url = link.get('href')
title = link.text.strip().replace(stripText, "")
read = readnum[0].text.strip("阅读数:")
comment = readnum[1].text.strip("评论数:")
data = {
'url': url,
'title': title,
'readnum': read,
'comment': comment
}
print(data)
def printOriginalData(links,readnum,stripText):
for link in links:
url = link.get('href')
title = link.text.strip().replace(stripText, "")
read = readnum[0].text.strip("阅读数:")
comment = readnum[1].text.strip("评论数:")
data = {
'url': url,
'title': title,
'readnum': read,
'comment': comment
}
print(data)
if __name__ == '__main__':
username = "stormdony"
getTranshipmentArticle(username)
print('------------------以下是原创文章--------------')
getOriginalArticle(username)
上面的程序,还有一个问题没有解决: 那就是分页的问题。
因为我的转载文章刚好只够一页,还不够分页的数量,所以需要添加多一条printTranshipmentData()
语句。
以后有时间在更新吧!!!
再次感谢这位 博友!!!