抓取csdn论坛

实现功能

  1. 获取论坛分类所有链接,并拼接成推荐精华页的完成的链接

  2. 获取推荐精华页的帖子状态,赏分,帖子标题,作者,发布时间,回复量,查看量,最后发表时间

  3. 置顶内容不爬取,只打印置顶内容的帖子标题,作者信息和帖子链接

  4. 跳过没有内容的版块,并打印出来

  5. 把获取到的内容添加到数据库

未实现功能

  1. 获取非技术论坛时遇到一个讨论帖子,前面没有帖子状态,出现index下标异常

  2. 未爬取推荐精华页的所有帖子(只实现了第一页的爬取)

  3. 未爬取帖子内容(帖子发布的内容和回复信息等等)

  4. 未爬取发帖人的个人信息(排名,发帖数,回帖数,结帖率等等)

总结:

  1. python的很多基础方法不知道

  2. 字符串操作不熟练

  3. xpath语法不熟练

  4. peewee很多方法不知道

  5. 马虎,判断帖子有没有内容时,后面忘加一个方法导致运行错误,找了半个多小时才找到

  6. 未实现功能应该都能解决,只是嫌麻烦

"""
抓取
解析
存储
"""
import re
import ast
from urllib import parse
import requests
from scrapy import Selector
import json
import time
from csdn_spider.models import * domain = 'https://bbs.csdn.net'
def get_nodes_json():
left_menu_text = requests.get('https://bbs.csdn.net/dynamic_js/left_menu.js?csdn').text
# print(left_menu_text)
nodes_str_match = re.search('forumNodes: (.*])',left_menu_text)
if nodes_str_match:
nodes_str = nodes_str_match.group(1).replace('null','None')
nodes_list = ast.literal_eval(nodes_str)
# print(nodes_list)
return nodes_list
return [] url_list = []
def process_nodes_list(nodes_list):
#将js的格式提取出url转换到list中
for item in nodes_list:
if 'url' in item:
if item['url']:
url_list.append(item['url'])
if 'children' in item:
process_nodes_list(item['children']) def get_levell_list(nodes_list):
levell_url = []
for item in nodes_list:
if 'url' in item and item['url']:
levell_url.append(item['url'])
return levell_url def get_last_list():
#获取最终需要抓取的url
nodes_list = get_nodes_json()
process_nodes_list(nodes_list)
levell_url = get_levell_list(nodes_list)
last_url = []
for url in url_list:
if url not in levell_url:
last_url.append(url)
all_urls = []
for url in last_url:
all_urls.append(parse.urljoin(domain, url+'/recommend'))
return all_urls def parse_list(url):
res_text = requests.get(url).text
sel = Selector(text=res_text)
all_sel = sel.xpath('//table[@class="forums_tab_table"]/tbody//tr')
if len(all_sel.extract()) != 0:
if str(re.search('没有帖子', all_sel.extract()[0])) != 'None':
print('没有帖子')
return
for tr in all_sel:
if (tr.xpath('td[@class="forums_topic"]/span[1]/text()').extract()) == ['[置顶]']:
print('发现置顶!!!')
print('置顶账号为:',tr.xpath('td[@class="forums_author"]/a/text()').extract()[0])
print('置顶内容为:',tr.xpath('td[@class="forums_topic"]/a[2]/text()').extract()[0])
print('置顶链接为:',parse.urljoin(domain,tr.xpath('td[@class="forums_topic"]/a[2]/@href').extract()[0]))
print('###############')
else:
#帖子状态
status = tr.xpath('td[@class="forums_topic_flag"]/span/text()').extract()[0]
# print('帖子状态', status)
#赏分
score = tr.xpath('td[@class="forums_score"]/em/text()').extract()[0]
# print('赏分', score)
#标题链接
topic_url = parse.urljoin(domain,tr.xpath('td[@class="forums_topic"]/a/@href').extract()[0])
# print('标题链接', topic_url)
#标题
topic_title = tr.xpath('td[@class="forums_topic"]/a/text()').extract()[0]
# print('标题', topic_title)
#标题id
topic_id = topic_url.split('/')[-1]
# print('标题id', topic_id)
#作者链接
id_url = tr.xpath('td[@class="forums_author"]/a/@href').extract()[0]
# print('作者链接', id_url)
#作者id
author_id = id_url.split('/')[-1]
# print('作者id', author_id)
#作者名称
author_name = tr.xpath('td[@class="forums_author"]/a/text()').extract()[0]
# print('作者名称', author_name)
#发布时间
create_time = datetime.strptime(tr.xpath('td[@class="forums_author"]/em/text()').extract()[0], '%Y-%m-%d %H:%M')
# print('发布时间', create_time)
#回复和查看的字符串
answer_info = (tr.xpath('td[@class="forums_reply"]/span/text()').extract()[0]).split('/')
#回复数量
answer_nums = answer_info[0]
# print('回复数量', answer_nums)
#查看数量
click_nums = answer_info[-1]
# print('查看数量', click_nums)
#最后发表时间
last_time = datetime.strptime(tr.xpath('td[@class="forums_last_pub"]/em/text()').extract()[0], '%Y-%m-%d %H:%M')
# print('最后发表时间', last_time)
#添加到数据库
Topic.create(id=topic_id,status=status,score=score,title_url=topic_url,title=topic_title,author_id=author_id,author_name=author_name,create_time=create_time,answer_nums=answer_nums,click_nums=click_nums,last_answer_time=last_time) if __name__=='__main__':
all_urls = get_last_list()
for url in all_urls:
print('正在连接:',url)
parse_list(url)
time.sleep(3)
from peewee import *#建立数据库连接
db = MySQLDatabase('spider', host='127.0.0.1', port=3306, user='root', password='123456lmr')
# class BaseModel(Model):
class Meta:
database = db '''
设计数据表的时候需要注意的点
char类型,尽量设置MAX(最大长度)
对于无法确定最大长度的,要采用TextField类型
default和null=True
主键无法设置int以外的类型(可能是版本问题)
''' #帖子list
class Topic(BaseModel):
#帖子名称
title = CharField()
#帖子链接
title_url = CharField(default='')
# #帖子内容
# content = TextField(default='')
#帖子id
id = IntegerField(primary_key=True)
#用户id
author_id = CharField()
#用户名称
author_name = CharField()
#创建时间
create_time = DateTimeField()
#回复数量
answer_nums = IntegerField(default=0)
#查看数量
click_nums = IntegerField(default=0)
# #点赞数量
# parised_nums = IntegerField(default=0)
# #结帖率
# jtl = FloatField(default=0.0)
#赏分
score = IntegerField(default=0)
#状态
status = CharField()
#最后回复时间
last_answer_time = DateTimeField() #帖子内容
class Answer(BaseModel):
#
topic_id = IntegerField()
author = CharField()
content = TextField(default="")
create_time = DateTimeField()
parised_nums = IntegerField(default=0) #点赞数 #用户
class Author(BaseModel):
name = CharField()
sign_name_id = CharField()
# id = CharField(primary_key=True)
click_nums = IntegerField(default=0) # 访问数
original_nums = IntegerField(default=0) # 原创数
forward_nums = IntegerField(default=0) # 转发数
rate = CharField(default=-1) # 排名
answer_nums = IntegerField(default=0) # 评论数
parised_nums = IntegerField(default=0) # 获赞数
desc = TextField(null=True)
industry = CharField(null=True)
location = CharField(null=True)
follower_nums = IntegerField(default=0) # 粉丝数
following_nums = IntegerField(default=0) # 关注数 if __name__ == '__main__':
# db.create_tables([Topic])
# db.create_tables([Answer])
# db.create_tables([Author])
db.create_tables([Topic, Answer, Author])

csdn论坛页抓取的更多相关文章

  1. python实现一个栏目的分页抓取列表页抓取

    python实现一个栏目的分页抓取列表页抓取 #!/usr/bin/env python # coding=utf-8 import requests from bs4 import Beautifu ...

  2. 简易数据分析 12 | Web Scraper 翻页——抓取分页器翻页的网页

    这是简易数据分析系列的第 12 篇文章. 前面几篇文章我们介绍了 Web Scraper 应对各种翻页的解决方法,比如说修改网页链接加载数据.点击"更多按钮"加载数据和下拉自动加载 ...

  3. 简易数据分析 10 | Web Scraper 翻页——抓取「滚动加载」类型网页

    这是简易数据分析系列的第 10 篇文章. 友情提示:这一篇文章的内容较多,信息量比较大,希望大家学习的时候多看几遍. 我们在刷朋友圈刷微博的时候,总会强调一个『刷』字,因为看动态的时候,当把内容拉到屏 ...

  4. 简易新闻网站NewsWeb-网页抓取

    本文转载自姚虎才子 今天做项目时用到java抓取网页内容,本以为很简单的一件事但是还是让我蛋疼了一会,网上资料一大堆但是都是通过url抓取网页内容,但是我要的是读取本地的html页面内容的方法,网上找 ...

  5. Python爬虫:新浪新闻详情页的数据抓取(函数版)

    上一篇文章<Python爬虫:抓取新浪新闻数据>详细解说了如何抓取新浪新闻详情页的相关数据,但代码的构建不利于后续扩展,每次抓取新的详情页时都需要重新写一遍,因此,我们需要将其整理成函数, ...

  6. python3爬虫再探之豆瓣影评数据抓取

    一个关于豆瓣影评的爬虫,涉及:模拟登陆,翻页抓取.直接上代码: import re import time import requests import xlsxwriter from bs4 imp ...

  7. Golang分布式爬虫:抓取煎蛋文章|Redis/Mysql|56,961 篇文章

    --- layout: post title: "Golang分布式爬虫:抓取煎蛋文章" date: 2017-04-15 author: hunterhug categories ...

  8. Python抓取成都房价信息

    Python里scrapy爬虫 scrapy爬虫,正好最近成都房价涨的厉害,于是想着去网上抓抓成都最近的房价情况,顺便了解一下,毕竟咱是成都人,得看看这成都的房子我以后买的起不~ 话不多说,进入正题: ...

  9. Python 爬虫抓取代理IP,并检测联通性

    帮朋友抓了一些代理IP,并根据测试联的通性,放在了不通的文件夹下.特将源码分享 注意: 1,环境Python3.5 2,安装BeautifulSoup4  requests 代码如下: 1 2 3 4 ...

随机推荐

  1. 【最小生成树之Kruskal例题-建设电力系统】-C++

    前置知识点Kruskal最短路算法,如果没掌握的请先去掌握! 描述 小明所在的城市由于下暴雪的原因,电力系统严重受损.许多电力线路被破坏,因此许多村庄与主电网失去了联系.政府想尽快重建电力系统,所以, ...

  2. 什么是常量?变量? if语句介绍

    1.python 的历史 2004 年 Django 的产生 phyton2与 python3 的区别 Python2:源码不统一,有重复的代码功能 Python3:源码统一,没有有重复的代码功能 2 ...

  3. centos 安装Python3 及对应的pip

    安装Python3安装Python依赖:yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqli ...

  4. 关于vue项目font字体图标库导入未显示的问题

    运行项目时,弹出以下信息:

  5. apache CXF Service 简单使用

    cxf介绍 框架官网:cxf.apache.org 支持多种协议: SOAP1.1,1.2 XML/HTTP CORBA(Common Object Request Broker Architectu ...

  6. Python基础总结之第四天开始【格式化‘字符串’】(新手可相互督促)

    年薪20万... 字符串格式化: 先看小案例-------: a = 'hello,my name is %s,I like %s.'%('XiaoHong','football') #在字符串中,[ ...

  7. 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印

    重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...

  8. web-inf与meta-inf

    /WEB-INF/web.xml Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则. /WEB-INF/classes/包含了站点所有用的 class 文件,包括 ser ...

  9. (技能篇)双机热备之Oracle切换故障处理

    背景: 以前做的的一个项目中使用了某国产双机热备产品,但是在数据库做双机热备时出现了一些问题,没办法.不得不研究一番了!经过两天的研究终于问题得以解决.将问题处理步骤记录下来以备后用,也希望能帮助到需 ...

  10. vue.js主要内容

    vue的主要内容 1.了解vue 2.vue开发环境的搭建和脚手架工具的使用 3.vue具体的指令和项目实战 1.了解vue 1.具备基础:html.css.js,模块化概念.ES6语法(简单即可) ...