首先我们爬取的帖子网址为:https://tieba.baidu.com/p/3138733512?see_lz=1&pn=1,该网址是只看楼主的帖子的网址,因此该网站的源代码内容均为楼主所发贴的内容,爬取起来也比较方便。我们发现需要爬取的帖子一共有5页,我们可以通过for循环来进行对每一页信息的爬取。
接下来我们来整体构建爬取的思路:
1,爬取该网页的源代码
2,用正则表达式提取所需内容
3,用正则匹配对所取内容进行精准修改以达到我们想要的内容
4,把内容写入到文件并显示写入进度
先上代码:
import requests
from bs4 import BeautifulSoup
import re
class Tools:
removeImg = re.compile('' )
removBr = re.compile('
')
removeHef = re.compile('')
removeA = re.compile('')
removeClass = re.compile('|' )
removeNull = re.compile(' ')
def remove(self,te):
te = re.sub(self.removeImg,'',te)
te = re. sub(self.removBr,'\n',te)
te = re.sub(self.removeHef,'',te)
te = re.sub(self.removeA,'',te)
te = re.sub(self.removeClass,'',te)
te = re.sub(self.removeNull, '', te)
return te
textTools = Tools()
def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def printTitle(html):
try:
soup = BeautifulSoup(html, "html.parser")
titleTag = soup.find_all('title')
patten = re.compile(r'(.*?) ', re.S)
title = re.findall(patten, str(titleTag))
return title
except:
return ""
def fillUnivlist(lis,li,html):
try:
patten = re.compile(r'(.*?)', re.S)
nbaInfo = re.findall(patten, str(html))
pattenFloor = re.compile(r'(\d*楼)', re.S)
floorText = re.findall(pattenFloor, str(html))
number = len(nbaInfo)
for i in range(number):
Info = textTools.remove(nbaInfo[i])
Info1 = textTools.remove(floorText[i])
lis.append(Info1)
li.append(Info)
except:
return ""
def writeText(titleText,fpath):
try:
with open(fpath, 'a', encoding='utf-8') as f:
f.write(str(titleText) + '\n')
f.write('\n')
f.close()
except:
return ""
def writeUnivlist(lis,li,fpath,num):
with open(fpath, 'a', encoding='utf-8') as f:
for i in range(num):
f.write(str(lis[i])+'\n')
f.write('*'*50 + '\n')
f.write(str(li[i]) + '\n')
f.write('*' * 50 + '\n')
f.close()
def main():
count = 0
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=1'
output_file = 'D:/StockInfo.txt'
html = getHTMLText(url)
titleText = printTitle(html)
writeText(titleText, output_file)
for i in range(5):
i = i + 1
lis = []
li = []
url = 'https://tieba.baidu.com/p/3138733512?see_lz=1&pn=' + str(i)
html = getHTMLText(url)
fillUnivlist(lis, li, html)
writeUnivlist(lis, li, output_file, len(lis))
count = count + 1
print("\r当前进度: {:.2f}%".format(count * 100 / 5), end="")
main()
下面来介绍每一步的具体实现:
首先是获取源代码,这个已经比较简单了,大多数获取源代码的方式都可以用这段代码来实现:
def getHTMLText(url):
try:
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = {'User-Agent': user_agent}
r = requests.get(url,headers = headers)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
其中的user_agent配置可以在网页的源代码中找到,其目的是将爬虫进行伪装成用户以此来获取更好的爬取体验
接下来我们要通过正则表达式来获取我们需要的“标题”,“帖子主要内容”以及“楼层”信息
通过分析源代码我们发现“标题”在
……
中可以找到,“帖子主要内容”在
中可以找到,“楼层”信息可以在
……
中找到。其中“…….”表示所要提取内容,我们分别用两个函数来实现对此的提取
def printTitle(html):
try:
soup = BeautifulSoup(html, "html.parser")
titleTag = soup.find_all('title')
patten = re.compile(r'(.*?) ', re.S)
title = re.findall(patten, str(titleTag))
return title
except:
#我们对每个方法都用try except 来保证其强健性。
return ""
def fillUnivlist(lis,li,html):
try:
patten = re.compile(r'(.*?)', re.S)
nbaInfo = re.findall(patten, str(html))
pattenFloor = re.compile(r'(\d*楼)', re.S)
floorText = re.findall(pattenFloor, str(html))
number = len(nbaInfo)
for i in range(number):
Info = textTools.remove(nbaInfo[i])
Info1 = textTools.remove(floorText[i])
lis.append(Info1)
li.append(Info)
except:
return ""