csdn论坛页抓取
抓取csdn论坛
实现功能
获取论坛分类所有链接,并拼接成推荐精华页的完成的链接
获取推荐精华页的帖子状态,赏分,帖子标题,作者,发布时间,回复量,查看量,最后发表时间
置顶内容不爬取,只打印置顶内容的帖子标题,作者信息和帖子链接
跳过没有内容的版块,并打印出来
把获取到的内容添加到数据库
未实现功能
获取非技术论坛时遇到一个讨论帖子,前面没有帖子状态,出现index下标异常
未爬取推荐精华页的所有帖子(只实现了第一页的爬取)
未爬取帖子内容(帖子发布的内容和回复信息等等)
未爬取发帖人的个人信息(排名,发帖数,回帖数,结帖率等等)
总结:
python的很多基础方法不知道
字符串操作不熟练
xpath语法不熟练
peewee很多方法不知道
马虎,判断帖子有没有内容时,后面忘加一个方法导致运行错误,找了半个多小时才找到
未实现功能应该都能解决,只是嫌麻烦
"""
抓取
解析
存储
"""
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论坛页抓取的更多相关文章
- python实现一个栏目的分页抓取列表页抓取
python实现一个栏目的分页抓取列表页抓取 #!/usr/bin/env python # coding=utf-8 import requests from bs4 import Beautifu ...
- 简易数据分析 12 | Web Scraper 翻页——抓取分页器翻页的网页
这是简易数据分析系列的第 12 篇文章. 前面几篇文章我们介绍了 Web Scraper 应对各种翻页的解决方法,比如说修改网页链接加载数据.点击"更多按钮"加载数据和下拉自动加载 ...
- 简易数据分析 10 | Web Scraper 翻页——抓取「滚动加载」类型网页
这是简易数据分析系列的第 10 篇文章. 友情提示:这一篇文章的内容较多,信息量比较大,希望大家学习的时候多看几遍. 我们在刷朋友圈刷微博的时候,总会强调一个『刷』字,因为看动态的时候,当把内容拉到屏 ...
- 简易新闻网站NewsWeb-网页抓取
本文转载自姚虎才子 今天做项目时用到java抓取网页内容,本以为很简单的一件事但是还是让我蛋疼了一会,网上资料一大堆但是都是通过url抓取网页内容,但是我要的是读取本地的html页面内容的方法,网上找 ...
- Python爬虫:新浪新闻详情页的数据抓取(函数版)
上一篇文章<Python爬虫:抓取新浪新闻数据>详细解说了如何抓取新浪新闻详情页的相关数据,但代码的构建不利于后续扩展,每次抓取新的详情页时都需要重新写一遍,因此,我们需要将其整理成函数, ...
- python3爬虫再探之豆瓣影评数据抓取
一个关于豆瓣影评的爬虫,涉及:模拟登陆,翻页抓取.直接上代码: import re import time import requests import xlsxwriter from bs4 imp ...
- Golang分布式爬虫:抓取煎蛋文章|Redis/Mysql|56,961 篇文章
--- layout: post title: "Golang分布式爬虫:抓取煎蛋文章" date: 2017-04-15 author: hunterhug categories ...
- Python抓取成都房价信息
Python里scrapy爬虫 scrapy爬虫,正好最近成都房价涨的厉害,于是想着去网上抓抓成都最近的房价情况,顺便了解一下,毕竟咱是成都人,得看看这成都的房子我以后买的起不~ 话不多说,进入正题: ...
- Python 爬虫抓取代理IP,并检测联通性
帮朋友抓了一些代理IP,并根据测试联的通性,放在了不通的文件夹下.特将源码分享 注意: 1,环境Python3.5 2,安装BeautifulSoup4 requests 代码如下: 1 2 3 4 ...
随机推荐
- BI之路学习笔记3--olap cube理解实例
为什么会产生OLAP? 随着数据库技术的发展应用,数据库存储的数据量从M字节以及G(千兆)字节过渡到T字节和P字节,同时,用户的查询需求也越来越复杂,设计的已不仅是查询或者操纵一张关系表中的一条或几条 ...
- py+selenium 报错NameError: name 'NoSuchElementException' is not defined【已解决】
报错:NameError: name 'NoSuchElementException' is not defined 如图 解决方法: 头部加一句:from selenium.common.exc ...
- 下载历史版本CentOS
搜索centos 进入主页面向下移动滚动找到 点击后向下移动,选择需要的版本进行tree 选择 OK!
- 洛谷P2598 [ZJOI2009]狼和羊的故事 题解
题目链接: https://www.luogu.org/problemnew/show/P2598 分析: 我们知道此题的目的是将狼和羊分割开,很容易想到狼在S,羊在T中. 首先,我们可以在狼,羊,空 ...
- 实验吧--web--你真的会php吗
---恢复内容开始--- 实验吧的一道题php审计题.拉下来写一写. http://ctf5.shiyanbar.com/web/PHP/index.php 打开之后说have fun 那就抓包来看看 ...
- HashSet源码分析:JDK源码系列
1.简介 继续分析源码,上一篇文章把HashMap的分析完毕.本文开始分析HashSet简单的介绍一下. HashSet是一个无重复元素集合,内部使用HashMap实现,所以HashMap的特征耶继承 ...
- [AOP拦截 ]SpringBoot+Quartz Aop拦截Job类中的方法
最近在工作使用boot+quartz整合,开发定时调度平台,遇到需要对Quartz的Job进行异常后将异常记录到日志表的操作,第一反应就想到了使用Spring的AOP,利用AfterThrowin ...
- Catalan公式
f(n)=f(1)*f(n-1)+f(2)*f(n-2)+f(3)*f(n-3)+......+f(n-1)*f(1) 例用:一个长度为n的无重复序列入栈的所有出栈方式
- [PTA] 数据结构与算法题目集 6-4 链式表的按序号查找 & 6-5 链式表操作集 & 6-6 带头结点的链式表操作集
带不带头结点的差别就是,在插入和删除操作中,不带头结点的链表需要考虑两种情况:1.插入(删除)在头结点.2.在其他位置. 6.4 //L是给定单链表,函数FindKth要返回链式表的第K个元素.如果该 ...
- 织梦(dede)底层模板概念、常用底层模板字段
织梦(dede)底层模板概念.常用底层模板字段 一.底层模板的概念以及调用方式: 1. 什么是底层模板? 底层模板不是一个模板! 他就是在实际页面当中所要显示的具体内容: 2. 底层模板的应用: 调用 ...