翻译案例(已失效)
现在翻译接口需要多传两个参数 获取机制不明确
# coding=utf-8
import requests
import json
import sys
class BaiduFanyi:
def __init__(self,trans_str):
self.trans_str = trans_str
self.lang_detect_url = "http://fanyi.baidu.com/langdetect"
self.trans_url = "http://fanyi.baidu.com/basetrans"
self.headers = {
"User-Agent":"Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36"}
def parse_url(self,url,data): #发送post请求,获取响应
response = requests.post(url,data=data,headers=self.headers)
return json.loads(response.content.decode())
def get_ret(self,dict_response):#提取翻译的结果
ret = dict_response["trans"][0]["dst"]
print("result is :",ret)
def run(self):#实现主要逻辑
#1.获取语言类型
#1.1 准备post的url地址,post_data
lang_detect_data = {
"query":self.trans_str}
#1.2 发送post请求,获取响应
lang = self.parse_url(self.lang_detect_url,lang_detect_data)["lan"]
#1.3 提取语言类型
#2.准备post的数据
trans_data = {
"query":self.trans_str,"from":"zh","to":"en"} if lang== "zh" else \
{
"query":self.trans_str,"from":"en","to":"zh"}
#3.发送请求,获取响应
dict_response = self.parse_url(self.trans_url,trans_data)
#4.提取翻译的结果
self.get_ret(dict_response)
if __name__ == '__main__':
trans_str= sys.argv[1]
baidu_fanyi = BaiduFanyi(trans_str)
baidu_fanyi.run()
快速筛选
如何寻找JS
加断点查看密码加密逻辑
网页版不好抓 可以尝试抓移动端接口
元素中找不到可以搜索所有文件找对应字段
reqeusts小技巧
cookies字典转换、URL编解码
不正规网站会触发SSL验证
1、reqeusts.util.dict_from_cookiejar 把cookie对象转化为字典
1.1. requests.get(url,cookies={})
2、请求 SSL证书验证
response=requests.get("https://www.12306.cn/mormhweb/",verify=False)
3、设置超时
response = requests.get(url,1)
4、配合状态码判断是否请求成功
assert response.status_code == 200
下面我们通过一个例子整体来看一下以上4点的用法
# coding=utf-8
import requests
from retrying import retry
headers={
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36"}
@retry(stop_max_attempt_number=3)
def _parse_url(url,method,data,proxies):
print("*"*20)
if method=="POST":
response = requests.post(url,data=data,headers=headers,proxies=proxies)
else:
response = requests.get(url,headers=headers,timeout=3,proxies=proxies)
assert response.status_code == 200
return response.content.decode()
def parse_url(url,method="GET",data=None,proxies={
}):
try:
html_str = _parse_url(url,method,data,proxies)
except:
html_str = None
return html_str
if __name__ == '__main__':
url = "www.baidu.com"
print(parse_url(url))
数据提取
什么是数据提取?
简单的来说,数据提取就是从响应中获取我们想要的数据的过程
数据分类
非结构化的数据:html等
处理方法:正则表达式、xpath
结构化数据:json,xml等
处理方法:转化为python数据类型
数据提取之JSON
由于把json数据转化为python内建数据类型很简单,所以爬虫中,如果我们能够找到返回json数据的URL,就会尽量使用这种URL
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。
那么问题来了:哪里能找到返回json的url呢?
1、使用chrome切换到手机页面
2、抓包手机app的软件
loads和dumps更实用
# coding=utf-8
import json
import requests
from parse_url import parse_url
from pprint import pprint
url = "https://m.douban.com/rexxar/api/v2/subject_collection/movie_showing/items?start=0&count=18&loc_id=108288"
html_str = parse_url(url)
# json.loads把json字符串转化为python类型
ret1 = json.loads(html_str)
# pprint(ret1) # 让格式更加美观
# print(type(ret1))
# json.dumps能够把python类型转化为json字符串
with open("douban.json","w",encoding="utf-8") as f:
f.write(json.dumps(ret1,ensure_ascii=False,indent=4)) # ensure_ascii=False 不进行转码 indent=4 缩进四格
# f.write(str(ret1))
# with open("douban.json","r",encoding="utf-8") as f:
# ret2 = f.read()
# ret3 = json.loads(ret2)
# print(ret3)
# print(type(ret3))
# 使用json.load提取类文件对象中的数据
with open("douban.json","r",encoding="utf-8") as f:
ret4 = json.load(f)
print(ret4)
print(type(ret4))
#json.dump能够把python类型放入类文件对象中
with open("douban1.json","w",encoding="utf-8") as f:
json.dump(ret1,f,ensure_ascii=False,indent=2)
# coding=utf-8
import re
from parse_url import parse_url
import json
url = "http://36kr.com/"
html_str = parse_url(url)
ret = re.findall("<script>var props=(.*?),locationnal=",html_str)[0]
with open("36kr.json","w",encoding="utf-8") as f:
f.write(ret)
ret = json.loads(ret)
print(ret)
豆瓣爬虫(已失效)
# coding=utf-8
import requests
import json
class DoubanSpider:
def __init__(self):
self.url_temp_list = [
{
"url_temp": "https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_american_hot/items?start={}&count=18&loc_id=108288",
"country": "US"
},
{
"url_temp": "https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_english_hot/items?start={}&count=18&loc_id=108288",
"country": "UK"
},
{
"url_temp": "https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_domestic_hot/items?start={}&count=18&loc_id=108288",
"country": "CN"
}
]
self.headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36"}
def parse_url(self, url): # 发送请求,获取响应
print(url)
response = requests.get(url, headers=self.headers)
return response.content.decode()
def get_content_list(self, json_str): # 提取是数据
dict_ret = json.loads(json_str)
content_list = dict_ret["subject_collection_items"]
total = dict_ret["total"]
return content_list, total
def save_content_list(self, content_list,country): # 保存
with open("douban.txt", "a", encoding="utf-8") as f:
for content in content_list:
content["country"] = country
f.write(json.dumps(content, ensure_ascii=False))
f.write("\n") # 写入换行符,进行换行
print("保存成功")
def run(self): # 实现主要逻辑
for url_temp in self.url_temp_list:
num = 0
total = 100 # 假设有第一页
while num < total + 18:
# 1.start_url
url = url_temp["url_temp"].format(num)
# 2.发送请求,获取响应
json_str = self.parse_url(url)
# 3.提取是数据
content_list, total = self.get_content_list(json_str)
# 4.保存
self.save_content_list(content_list,url_temp["country"])
# if len(content_list)<18:
# break
# 5.构造下一页的url地址,进入循环
num += 18
if __name__ == '__main__':
douban_spider = DoubanSpider()
douban_spider.run()
重点
### 寻找登录的post地址
- 在form表单中寻找action对应的url地址
- post的数据是input标签中name的值作为键,真正的用户名密码作为值的字典,post的url地址就是action对应的url地址
- 抓包,寻找登录的url地址
- 勾选perserve log按钮,防止页面跳转找不到url
- 寻找post数据,确定参数
- 参数不会变,直接用,比如密码不是动态加密的时候
- 参数会变
- 参数在当前的响应中
- 通过js生成
### 定位想要的js
- 选择会触发js时间的按钮,点击event listener,找到js的位置
- 通过chrome中的search all file来搜索url中关键字
- 添加断点的方式来查看js的操作,通过python来进行同样的操作
### 安装第三方模块
- pip install retrying
- 下载源码解码,进入解压后的目录,```python setup.py install```
- `***.whl` 安装方法 `pip install ***.whl`
### json使用注意点
- json中的字符串都是双引号引起来的
- 如果不是双引号
- eval:能实现简单的字符串和python类型的转化
- replace:把单引号替换为双引号
- 往一个文件中写入多个json串,不再是一个json串,不能直接读取
- 一行写一个json串,按照行来读取