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 ...
随机推荐
- 洛谷 P4013 数字梯形问题【最大费用最大流】
第一问:因为每个点只能经过一次,所以拆点限制流量,建(i,i',1,val[i]),然后s向第一行建(s,i,1,0),表示每个点只能出发一次,然后最后一行连向汇点(i',t,1,0),跑最大费用最大 ...
- ionic2 如何引入第三方cordova插件
例如:cordova-plugin-wechat 这个插件可以做微信登录,分享支付等 首先第一步:ionic plugin add cordova-plugin-wechat --variable w ...
- Ocelot(十)- 路由
Ocelot的主要功能是接收传入的http请求并将其转发到下游服务.Ocelot目前仅以另一个http请求的形式支持此功能(将来可能是任何传输机制). Ocelot描述了将一个请求路由到另一个请求作为 ...
- Go语言多态
总结一下Go语言中多态 package main import "fmt" //申明一个函数类型 type FuncMs func(int ,int) int //加法 func ...
- 关于自增id 你可能还不知道
导读:在使用MySQL建表时,我们通常会创建一个自增字段(AUTO_INCREMENT),并以此字段作为主键.本篇文章将以问答的形式讲述关于自增id的一切. 注: 本文所讲的都是基于Innodb存储引 ...
- hdu 2121 Ice_cream’s world II (无定根最小树形图)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目大意: 有n个点,有m条单向路,问这n个点组成最小树形图的最小花费. 解题思路: 1:构造 ...
- bnu oj 13288 Bi-shoe and Phi-shoe
题目链接: http://www.bnuoj.com/contest/problem_show.php?pid=13288 题目大意: 给出一个n,然后给出n个幸运数([1,m]中不能被m整除的数的数 ...
- 递推DP UVA 607 Scheduling Lectures
题目传送门 题意:教授给学生上课,有n个主题,每个主题有ti时间,上课有两个限制:1. 每个主题只能在一节课内讲完,不能分开在多节课:2. 必须按主题顺序讲,不能打乱.一节课L时间,如果提前下课了,按 ...
- 题解报告:hdu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...
- Linux单机环境下HDFS伪分布式集群安装操作步骤v1.0
公司平台的分布式文件系统基于Hadoop HDFS技术构建,为开发人员学习及后续项目中Hadoop HDFS相关操作提供技术参考特编写此文档.本文档描述了Linux单机环境下Hadoop HDFS伪分 ...