爬虫代码

tieba_spider.py:

# -*- coding: utf-8 -*-

import scrapy
import json
from tieba.items import ThreadItem, PostItem, CommentItem
import helper
import time

class TiebaSpider(scrapy.Spider):
name = "tieba"
cur_page = 1 #modified by pipelines (open_spider)
end_page = 9999
filter = None
see_lz = False

def parse(self, response): #forum parser
for sel in response.xpath(‘//li[contains(@class, "j_thread_list")]‘):
data = json.loads(sel.xpath(‘@data-field‘).extract_first())
item = ThreadItem()
item[‘id‘] = data[‘id‘]
item[‘author‘] = data[‘author_name‘]
item[‘reply_num‘] = data[‘reply_num‘]
item[‘good‘] = data[‘is_good‘]
if not item[‘good‘]:
item[‘good‘] = False
item[‘title‘] = sel.xpath(‘.//div[contains(@class, "threadlist_title")]/a/text()‘).extract_first()
if self.filter and not self.filter(item["id"], item["title"], item[‘author‘], item[‘reply_num‘], item[‘good‘]):
continue
#filter过滤掉的帖子及其回复均不存入数据库

yield item
meta = {‘thread_id‘: data[‘id‘], ‘page‘: 1}
url = ‘http://tieba.baidu.com/p/%d‘ % data[‘id‘]
if self.see_lz:
url += ‘?see_lz=1‘
yield scrapy.Request(url, callback = self.parse_post, meta = meta)
next_page = response.xpath(‘//a[@class="next pagination-item "]/@href‘)
self.cur_page += 1
if next_page:
if self.cur_page <= self.end_page:
yield self.make_requests_from_url(next_page.extract_first())

def parse_post(self, response):
meta = response.meta
has_comment = False
for floor in response.xpath("//div[contains(@class, ‘l_post‘)]"):
if not helper.is_ad(floor):
data = json.loads(floor.xpath("@data-field").extract_first())
item = PostItem()
item[‘id‘] = data[‘content‘][‘post_id‘]
item[‘author‘] = data[‘author‘][‘user_name‘]
item[‘comment_num‘] = data[‘content‘][‘comment_num‘]
if item[‘comment_num‘] > 0:
has_comment = True
content = floor.xpath(".//div[contains(@class,‘j_d_post_content‘)]").extract_first()
#以前的帖子, data-field里面没有content
item[‘content‘] = helper.parse_content(content, True)
#以前的帖子, data-field里面没有thread_id
item[‘thread_id‘] = meta[‘thread_id‘]
item[‘floor‘] = data[‘content‘][‘post_no‘]
#只有以前的帖子, data-field里面才有date
if ‘time‘ in data[‘content‘].keys():
item[‘time‘] = data[‘content‘][‘date‘]
#只有以前的帖子, data-field里面才有date
else:
item[‘time‘] = floor.xpath(".//span[@class=‘tail-info‘]")\
.re_first(r‘[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}‘)
yield item
if has_comment:
url = "http://tieba.baidu.com/p/totalComment?tid=%d&fid=1&pn=%d" % (meta[‘thread_id‘], meta[‘page‘])
if self.see_lz:
url += ‘&see_lz=1‘
yield scrapy.Request(url, callback = self.parse_comment, meta = meta)
next_page = response.xpath(u".//ul[@class=‘l_posts_num‘]//a[text()=‘下一页‘]/@href")
if next_page:
meta[‘page‘] += 1
url = response.urljoin(next_page.extract_first())
yield scrapy.Request(url, callback = self.parse_post, meta = meta)

def parse_comment(self, response):
comment_list = json.loads(response.body)[‘data‘][‘comment_list‘]
for value in comment_list.values():
comments = value[‘comment_info‘]
for comment in comments:
item = CommentItem()
item[‘id‘] = comment[‘comment_id‘]
item[‘author‘] = comment[‘username‘]
item[‘post_id‘] = comment[‘post_id‘]
item[‘content‘] = helper.parse_content(comment[‘content‘], False)
item[‘time‘] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(comment[‘now_time‘]))
yield item

helper.py:

# -*- coding: utf-8 -*-

import re
import urllib2
from bs4 import BeautifulSoup
import emotion

def is_ad(s): #判断楼层是否为广告
ad = s.xpath(u".//span[contains(text(), ‘广告‘)]")
# 广告楼层中间有个span含有广告俩字
return ad

def parse_content(content, is_post):
if not content or not content.strip():
return None
content = content.replace(‘\r‘, ‘\n‘) #古老的帖子会出现奇怪的\r
s = BeautifulSoup(content, ‘lxml‘)
if is_post:
s = s.div #post 外层有个div

l = list(s.children)
for i in range(len(l)):
parse_func = (is_str, is_br, is_img, is_video, other_case)
for func in parse_func:
try:
ret = func(l[i])
except:
continue
if ret is not False:
l[i] = ret
break

return strip_blank(‘‘.join(l))

def strip_blank(s): #按个人喜好去掉空白字符
s = re.sub(r‘\n[ \t]+\n‘, ‘\n‘, s)
s = re.sub(r‘ +‘, ‘ ‘, s) #去掉多余的空格
s = re.sub(r‘\n\n\n+‘, ‘\n\n‘, s) #去掉过多的连续换行
return s.strip()

def is_str(s):
if s.name:
return False
#NavigableString类型需要手动转换下
return unicode(s)

def is_br(s):
if s.name == ‘br‘:
return ‘\n‘
return False

def is_img(s):
# 处理了部分表情
if s.name == ‘img‘:
src = unicode(s.get(‘src‘))
return emotion.get_text(src)
return False

def is_video(s):
t = unicode(s.get(‘class‘))
if ‘video‘ in t:
url = s.find(‘a‘).get(‘href‘)
return ‘ ‘ + getJumpUrl(url) + ‘ ‘
return False

#bs带的get_text功能,很好很强大
#粗体红字之类的都一句话搞定了
def other_case(s):
return s.get_text()

时间: 2024-10-21 17:53:22

爬虫代码的相关文章

Node.js(十三)——Promise重构爬虫代码

在重构代码之前,先要了解下什么是https? https协议:基于ssl/tls的http协议,所有的数据都是在 ssl/tls协议的封装之上传输的,也就是说https协议是在http协议基础上 添加了ssl/tls握手以及数据加密传输,因此这就是两者之间最大的区别. https模块专门处理加密访问的,区别在于搭建https服务器的时候需要有ssl证书. 模拟搭建https服务器 var https = require('https') var fs = require('fs')//文件系统模

优酷电视剧爬虫代码实现一:下载解析视频网站页面(3)补充知识点:XPath无效怎么办?

XPath无效怎么办?明明XPath是通过定位子节点,copy xpath得到的,理论上是正确的 XPath无效怎么办?明明XPath是通过按F12定位符再copy XPath得到的,可是放在代码里就是不对呢? 前提:优酷电视剧爬虫代码实现一:下载解析视频网站页面(2)工作量已经完成.基于这个基础,进一步完善代码 1.新建页面解析接口. package com.dajiangtai.djt_spider.service; import com.dajiangtai.djt_spider.enti

python爬虫代码

原创python爬虫代码 主要用到urllib2.BeautifulSoup模块 #encoding=utf-8 import re import requests import urllib2 import datetime import MySQLdb from bs4 import BeautifulSoup import sys reload(sys) sys.setdefaultencoding("utf-8") class Splider(object): def __in

python写的简单有效的爬虫代码

python写的简单有效的爬虫代码 by 伍雪颖 import re import urllib def getHtml(url): html = urllib.urlopen(url) scode = html.read() return scode def getImage(source): reg = r'src="(.*?\.jpg)"' imgre = re.compile(reg) images = re.findall(imgre,source) x = 0 for i

Python的几个爬虫代码整理(网易云、微信、淘宝、今日头条)

整理了一下网易云歌曲评论抓取.分析好友信息抓取.淘宝宝贝抓取.今日头条美图抓取的一些代码 抓取网易云评论 进入歌曲界面: http://music.163.com/#/song?id=453185824 找到如下的数据源: 贴一段Lyrichu的代码: (运行环境为P2.7) # -*- coding: utf-8 -*-# @Time : 2017/3/28 8:46# @Author : Lyrichu# @Email : [email protected]# @File : NetClou

爬虫代码实现三:打通爬虫项目的下载、解析、存储流程

1.新建一个存储接口IStoreService package com.dajiangtai.djt_spider.service; import com.dajiangtai.djt_spider.entity.Page; /** * 数据存储接口 * @author Administrator * */public interface IStoreService { public void store(Page page);} 2.新建一个存储接口实现类ConsoleStoreService

【最新原创】中国移动(中国联通)_通信账单,详单,个人信息抓取爬虫代码

概要: 1.因为公司需要,就花了一点时间写了一下三大运营商通信数据的抓取,涉及到Web上你所看得到的一切数据. 代码没啥技术含量,重点在于抓包分析过程.期间遇到了很多未知的困难,都一一克服了. 2.由于抓取数据的隐私性,我们的抓包是假设在用户已知自己数据被抓取,并且同意告知短信验证码的情况下进行的, 不属于黑客范畴! 3.整个过程,包括重建数据库表结构,解析json等如同逆向运营商的数据库一般.总体来说,三大运营商更新频率不算频繁,还算较稳定,数据结构,网页结构等都不会做很大的变动. 整体效果如

爬虫代码实现五:解析所有分页url并优化解析实现类

如图,我们进入优酷首页,可以看到电视剧列表,我们称这个页面为电视剧列表页,而点击进入某个电视剧,则称为电视剧详情页.那么如何获取所有分页以及对应的详情页呢,通过下面的分页得到. 因此,首先,我们将StartDSJCount中的url从详情页改为列表页, 由于这里我们想获取列表页对应的所有分页详情页,因此,我们需要在page中添加一个urlList属性,然后给它get/set方法.这里如果自动生成set方法,那么我们在set时还要new一个list,有点麻烦,这里我们先暂时只自动生成get方法,然

java爬虫学习日记2-宽度优先爬虫代码实现

爬虫两种方式--宽度优先和带偏好爬虫 先复习下上次学了什么: URL和URI的结构组成 根据指定网址爬取网站内容(get方式和post方式) 上一日记中学到了抓取单个页面内容的方法,但实际项目中则需要爬虫遍历互联网,把互联网中相关的页面都抓取回来.那么爬虫是怎样遍历互联网,把页面抓取下来的呢?首先互联网可以开成是一个"图",每个页面可以看作一个节点,链接可以看作是"有向边".因此能够通过图的方式对互联网这超级大"图"进行遍历.图的遍历通常可分为宽

scrapy按顺序启动多个爬虫代码片段(python3)

问题:在运行scrapy的过程中,如果想按顺序启动爬虫怎么做? 背景:爬虫A爬取动态代理ip,爬虫B使用A爬取的动态代理ip来伪装自己,爬取目标,那么A一定要在B之前运行该怎么做? IDE:pycharm 版本:python3 框架:scrapy 系统:windows10 代码如下:(请自行修改) # !/usr/bin/env python3 # -*- coding:utf-8 -*- from scrapy import cmdline from twisted.internet impo