爬取一BBS论坛所有帖子名

浏览: 1552

Clipboard Image.png

爬取中国政法大学的 法大BBS,之前的IP被封掉了。今天我改了下代码,加入了休息时间,降低访问的频率。

首先要爬该BBS里所有的标题,那么首先应该知道是哪个版块的,版块的链接是什么,这些链接的特点有什么规律吗,还有保存起来。

打开浏览器,按住F12键,查看DOM节点,发现版块名,链接都是处于“dt”标签中,而且查看页面源码,按住Ctrl+F查找''dt'',发现刚好35个,正好与版块的个数相等。

上面解决了版块链接、版块名的问题,查看各个板块的页码数也与上面方法类似。只要找到唯一的能确定的标签就能抓取。

# -*- coding=utf-8 -*-

from bs4 import BeautifulSoup
import urllib.request
import time


#获取板块的链接
def get_Bankuan_link(url):
link_list = [] #用来收集板块的链接
html = urllib.request.urlopen(url)
bsObj = BeautifulSoup(html, "lxml")
#bsObj.find_all('dt')返回的是列表,所以要遍历
for node in bsObj.find_all('dt'):
# 遍历每个<dt>节点内的节点,
#如<a href="forum.php?mod=forumdisplay&fid=67">校园生活</a>
#来获取链接和板块名字
try:
node_link = node.contents[0]['href']
node_html = urllib.request.urlopen(url + node_link)
node_bsObj = BeautifulSoup(node_html,"lxml") #进入板块内
judge = node_bsObj.find('input', {'name': 'custompage'})#找到页码所对应的代码
if judge is not None: #判断该板块是否有页码
link_list.append(node_link)
except:
continue
time.sleep(1)

#link_list.append(node_link)
return link_list #返回列表



#获取板块名
def get_Bankuan_name(url):
name_list = [] #用来收集板块名
html = urllib.request.urlopen(url)
bsObj = BeautifulSoup(html, "lxml")
#bsObj.find_all('dt')返回的是列表,所以要遍历。另外要清理不合规矩的板块
for node in bsObj.find_all('dt'):
try:
node_link = node.contents[0]['href']
node_html = urllib.request.urlopen(url + node_link)
node_bsObj = BeautifulSoup(node_html, "lxml")
judge = node_bsObj.find('input', {'name': 'custompage'})
if judge is not None:
name_list.append(node.contents[0].string)
except:
continue
time.sleep(1)
return name_list



#获取板块最大页数
def get_page_max_list(url,error_count = 1): #error_count=1方面函数内全局的对错误的计数不受for限制
page_max_list = []
Bankuan_link_list = get_Bankuan_link(url) #获取板块的链接,返回的是列表类型
Bankuan_name_list = get_Bankuan_name(url) #获取板块的名,列表
for x in Bankuan_link_list:
html = urllib.request.urlopen(url + x)
bsObj = BeautifulSoup(html, "lxml")
error = Bankuan_link_list.index(x) #error变量是为了后面遇到问题时候能标记到底是哪个板块的问题
error_Bankuan_name = Bankuan_name_list[error]
try:
num = bsObj.find('input', {'name': 'custompage'}).next_sibling.string[3:-2] #[3:-2]收集字符串从左起第四个 与 从右起倒数第二个 之间的字符串
page_max_list.append(num)
except:
print("Error%d: "%error_count,"%s 版块的get_page_max_list无法解决该板块,"需要自己动手查找该页面页数"%error_Bankuan_name,'\n', "该版块的网址是: http://bbs.csu.edu.cn/bbs/%s "%x, '\n'
"在版块名、版块链接列表中的第%d位置"%error)
print("="*100)
error_count = error_count + 1
time.sleep(1)
return page_max_list



#base_url:BBS的链接
#bankuan_url:BBS内某一板块的url
def get_BBS_all_article_title(file_name, pages_count, bankuan_url, base_url ='http://bbs.csu.edu.cn/bbs/', title_count = 1):
file_name = file_name+'.txt'
f = open(r'E:/Python/Spider_Net/未爬取的BBS/%s'%file_name, 'a')
html = urllib.request.urlopen(base_url+bankuan_url)
print('正在写入%s文件'%file_name)
for x in range(int(pages_count)):
page_num = x + 1
URL = base_url + bankuan_url + '&page=%d'%page_num
html = urllib.request.urlopen(URL)
#print('='*20,'正在写入%s文件'%file_name,'已经写了%d条帖子标题'%numlist_of_title)
try:
html = html.read().decode('gbk')
except:
continue
bsObj = BeautifulSoup(html, "lxml")
JieDian = bsObj.find_all("a", {"class": "s xst"})
for y in JieDian:
print(' ' * 15, '正在写入 %s文件' % file_name, ' 已经写了%d条帖子标题' % title_count, y.string)
try:
f.write(y.string + '\n')
title_count = title_count + 1
except:
continue
time.sleep(1)


===========================================================

#初始化bbs的链接
base_url = 'http://bbs.cupl.edu.cn/'

File_name = get_Bankuan_name(base_url)
Pages_count = get_page_max_list(base_url)
Bankuan_link = get_Bankuan_link(base_url)
print(File_name)
print(Pages_count)
print(Bankuan_link)


for i in range(len(File_name)):
file_name = File_name[i]
pages_count = Pages_count[i]
bankuan_link = Bankuan_link[i]
get_BBS_all_article_title(file_name, pages_count, bankuan_link,base_url)

完美!


欢迎大家关注我的

                      简书账号 邓旭东HIT

                      知乎账号 邓旭东HIT

                      公众号 大邓带你玩转python

Clipboard Image.png

推荐 0
本文由 邓旭东HIT 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册