Python多线程豆瓣影评API接口爬虫
爬虫库
使用简单的requests库,这是一个阻塞的库,速度比较慢。
解析使用XPATH表达式
总体采用类的形式
多线程
使用concurrent.future并发模块,建立线程池,把future对象扔进去执行即可实现并发爬取效果
数据存储
使用Python ORM sqlalchemy保存到数据库,也可以使用自带的csv模块存在CSV中。
API接口
因为API接口存在数据保护情况,一个电影的每一个分类只能抓取前25页,全部评论、好评、中评、差评所有分类能爬100页,每页有20个数据,即最多为两千条数据。
因为时效性原因,不保证代码能爬到数据,只是给大家一个参考思路,上代码:
from datetime import datetime
import random
import csv
from concurrent.futures import ThreadPoolExecutor, as_completed
from lxml import etree
import pymysql
import requests
from models import create_session, Comments
#随机UA
USERAGENT = [
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
'Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; ) AppleWebKit/534.12 (KHTML, like Gecko) Maxthon/3.0 Safari/534.12'
]
class CommentFetcher:
headers = {'User-Agent': ''}
cookie = ''
cookies = {'cookie': cookie}
# cookie为登录后的cookie,需要自行复制
base_node = '//div[@class="comment-item"]'
def __init__(self, movie_id, start, type=''):
'''
:type: 全部评论:'', 好评:h 中评:m 差评:l
:movie_id: 影片的ID号
:start: 开始的记录数,0-480
'''
self.movie_id = movie_id
self.start = start
self.type = type
self.url = 'https://movie.douban.com/subject/{id}/comments?start={start}&limit=20&sort=new_score\&status=P&percent_type={type}&comments_only=1'.format(
id=str(self.movie_id),
start=str(self.start),
type=self.type
)
#创建数据库连接
self.session = create_session()
#随机useragent
def _random_UA(self):
self.headers['User-Agent'] = random.choice(USERAGENT)
#获取api接口,使用get方法,返回的数据为json数据,需要提取里面的HTML
def _get(self):
self._random_UA()
res = ''
try:
res = requests.get(self.url, cookies=self.cookies, headers=self.headers)
res = res.json()['html']
except Exception as e:
print('IP被封,请使用代理IP')
print('正在获取{} 开始的记录'.format(self.start))
return res
def _parse(self):
res = self._get()
dom = etree.HTML(res)
#id号
self.id = dom.xpath(self.base_node + '/@data-cid')
#用户名
self.username = dom.xpath(self.base_node + '/div[@class="avatar"]/a/@title')
#用户连接
self.user_center = dom.xpath(self.base_node + '/div[@class="avatar"]/a/@href')
#点赞数
self.vote = dom.xpath(self.base_node + '//span[@class="votes"]/text()')
#星级
self.star = dom.xpath(self.base_node + '//span[contains(@class,"rating")]/@title')
#发表时间
self.time = dom.xpath(self.base_node + '//span[@class="comment-time "]/@title')
#评论内容 所有span标签class名为short的节点文本
self.content = dom.xpath(self.base_node + '//span[@class="short"]/text()')
#保存到数据库
def save_to_database(self):
self._parse()
for i in range(len(self.id)):
try:
comment = Comments(
id=int(self.id[i]),
username=self.username[i],
user_center=self.user_center[i],
vote=int(self.vote[i]),
star=self.star[i],
time=datetime.strptime(self.time[i], '%Y-%m-%d %H:%M:%S'),
content=self.content[i]
)
self.session.add(comment)
self.session.commit()
return 'finish'
except pymysql.err.IntegrityError as e:
print('数据重复,不做任何处理')
except Exception as e:
#数据添加错误,回滚
self.session.rollback()
finally:
#关闭数据库连接
self.session.close()
#保存到csv
def save_to_csv(self):
self._parse()
f = open('comment.csv', 'w', encoding='utf-8')
csv_in = csv.writer(f, dialect='excel')
for i in range(len(self.id)):
csv_in.writerow([
int(self.id[i]),
self.username[i],
self.user_center[i],
int(self.vote[i]),
self.time[i],
self.content[i]
])
f.close()
if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=4) as executor:
futures = []
for i in ['', 'h', 'm', 'l']:
for j in range(25):
fetcher = CommentFetcher(movie_id=26266893, start=j * 20, type=i)
futures.append(executor.submit(fetcher.save_to_csv))
for f in as_completed(futures):
try:
res = f.done()
if res:
ret_data = f.result()
if ret_data == 'finish':
print('{} 成功保存数据'.format(str(f)))
except Exception as e:
f.cancel()
Python多线程豆瓣影评API接口爬虫的更多相关文章
- 用Python调用华为云API接口发短信
[摘要] 用Python调用华为云API接口实现发短信,当然能给调用发短信接口前提条件是通过企业实名认证,而且有一个通过审核的短信签名,话不多说,showcode #!/usr/bin/python3 ...
- python使用zabbix的API接口
一.实验环境 python3.6.6 zabbix 3.0.9 二.实验目的 了解Zabbix的API接口格式 通过python实现登陆zabbix服务,获得登陆token 通过python检索zab ...
- python访问cloudstack的api接口
1.CloudStack API 如同 AWS API 一样,CloudStack API 也是基于 Web Service,可以使用任何一种支持 HTTP 调用的语言(例如 Java,python, ...
- Java多线程:实现API接口创建线程方式详解
先看例子: /**实现Runnable接口创建线程步骤: * 1.创建一个实现Runnable接口的类 * 2.重写Runnable类中抽象的run()方法 * 3.创建实现类的对象 * 4.声明Th ...
- 简单实现Python调用有道API接口(最新的)
# ''' # Created on 2018-5-26 # # @author: yaoshuangqi # ''' import urllib.request import urllib.pars ...
- Python实现简单的API接口
get方法 代码实现 # coding:utf-8 import json from urlparse import parse_qs from wsgiref.simple_ ...
- 利用python多线程模块实现模拟接口并发
import requestsimport jsonimport threadingimport timeimport uuid class postrequests(): def __init__( ...
- python 多线程,多进程,高效爬虫
1.多线程from concurrent.futures import ThreadPoolExecutor import requests def fetch_async(url): respons ...
- 使用Python解析豆瓣上Json格式数据
现在的API接口多为xml或json,json解析更简洁相对xml来说 以豆瓣的API接口为例,解析返回的json数据: https://api.douban.com/v2/book/1220562 ...
随机推荐
- ppt自动制作器
讲一篇论文导入进入,自动生成该论文的展示ppt,啧啧啧,想想岂不是很美妙
- MVC、MVP和MVVM的更简单易懂的理解
本篇转自网络: 一.MVC MVC模式的意思是,软件可以分成三个部分. 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 各部分之间的通信方式如下. ...
- 2017 JUST Programming Contest 3.0 D. Dice Game
D. Dice Game time limit per test 1.0 s memory limit per test 256 MB input standard input output stan ...
- 转-用Eclipse 开发Dynamic Web Project应用程序
简介:本文仅简单介绍基于Eclipse开发Dynamic Web Project应用下的JSP,Servlet及TOMCAT数据源的配置和开发. 软件环境: Eclipse Java EE IDE f ...
- windows下Python的安装,以及IDLE的使用
一.Python的下载安装 (1)python的windows安装包可以从https://www.python.org 网址中下载,可以下载3.4版本的或者2.7版本的.(2)下载后直接运行即可.然后 ...
- [转]Php MySql Class
本文转自:http://www.cnblogs.com/noevil/archive/2010/11/06/1870864.html <?php /** * 数据库操作类 * * @aut ...
- spring常用注解笔记
spring常用注解解释: 1. Mybatis的映射文件xxxMapper.xml中resultMap标签的作用 resultMap标签是为了映射select查询出来结果的集合,其主要 作用是将实体 ...
- sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别
sh/bash/csh/Tcsh/ksh/pdksh等shell本质区别 1. Shell脚本的书写 在写Shell脚本时,往往第一行要注明用什么解释器来解释这个脚本. 如#!/bin/bash即用/ ...
- 源代码管理git的使用
Git ----本地仓库---- 1.新建一个“本地仓库” git init 2.配置仓库 ①告诉git你是谁 git config user.name syl ②告诉git怎么联系你 git con ...
- H.264学习笔记1——相关概念
此处记录学习AVC过程中的一些基本概念,不定时更新. frame:帧,相当于一幅图像,包含一个亮度矩阵和两个色度矩阵. field:场,一帧图像,通过隔行扫描得到奇偶两场,分别称为顶场和底场或奇场和偶 ...