Python3 爬虫工作的一些总结

闲着没事,我也写一下我自己用到的一些最简单的爬虫所需的技术和工具,以后可能就不想写爬虫了,毕竟爬虫深似海!哎?,也为自己做一个笔记,如果能帮到部分爬虫新手的话就更好了
下图是我在看到的一幅图片,说出了我的心声,献给入爬虫坑的新手们。
在这里插入图片描述
而且现在基本都是抓取APP数据,说简单也简单,说难是真TMD难!!
简单:
app的数据比web端数据更容易抓取,基本都是http、https协议,返回的数据格式也相对规整,
大多是json格式
困难:
1.需要反编译的知识,需要分析加密算法
2.需要脱壳+反编译
3.需要破解各式各类的签名,证书.
所以一个爬虫工程师慢慢就需要掌握以下技能:
java编程基础
android编程基础
app逆向
app脱壳
破解加密
....
从入门到全栈?
最最最重要的!!!
爬虫岗位一般都是公司边缘化岗位,而且岗位也不多,所以工资什么的,明白了吧,能不转爬虫就别转爬虫吧。

文章目录

  • 后续有时间补上

正则篇

  • 因为我是用爬虫来抓取文章的,一般就是提取文章数据,或者去除下标签之类的,顺便说一下我这几步正则只对标签做处理,没有处理到任何文字, 当然style样式除外。

需求一: 要求文章只需要保存p和img标签,其他标签全部都去掉
需求二: 去掉p标签和img标签的其他style样式,当然我那个img标签里面的图片src是上传到七牛云上面的。
当然如果读者 有其他需求的正则,我有空也可以帮忙写一下

# 去掉除了p标签和Img标签之外的其他标签
import re
content = """<div class="__reader_view_article_wrap_694501494498835__"><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/adc1249ecb3140ec8e7037f37014c795" img_width="708" img_height="145" alt="ofo破产?官方声明来了!" inline="0"><p class="pgc-img-caption"></p></div><blockquote><p>ofo回应破产传闻:消息严重不实,目前运营一切正常。此前新京报称,ofo运营主体拜克洛克首次现身全国...</p></blockquote><p class="ql-align-justify">本文来自全天候科技,阅读更多请登陆www.awtmt.com或华尔街见闻APP。</p><p class="ql-align-justify">4月2日,全国企业破产重整案件信息网显示,ofo运营主体之一北京拜克洛克科技有限公司作为“被申请人”而出现,申请人为聂艳,日期是3月25日,办理法院为北京海淀区人民法院。多家媒体质疑ofo是否陷入破产危机。</p><p class="ql-align-justify">下午,ofo回应破产传闻:消息严重不实,目前运营一切正常。此前新京报称,ofo运营主体拜克洛克首次现身全国破产信息网。</p><div class="pgc-img"><img src="http://p1.pstatp.com/large/pgc-image/84657696ee424b6399b4a5a992188d04" img_width="1080" img_height="1920" alt="ofo破产?官方声明来了!" inline="0"><p class="pgc-img-caption"></p></div><p class="ql-align-justify">在此声明之前,ofo一直处于舆论的风口浪尖,从明星创业公司到濒临破产,ofo快速经历了这一切过程。</p><h1 class="ql-align-center">退押金风波</h1><p class="ql-align-justify">2018年12月中旬,ofo待退押金总额一再刷新。据全天候科技获悉,截至12月18日20时37分,排队退押用户数突破1000万。</p><p class="ql-align-justify">ofo用户押金主要有99元与199元两种。如果以99元/位计算,保守估计,ofo需退还押金总额约10亿元;但若以199元/位计算,那么ofo需要退还高达近20亿元的押金。</p><div class="pgc-img"><img src="http://p3.pstatp.com/large/pgc-image/7c9fbdb6c3d1484d833cbfc4d55ad406" img_width="438" img_height="529" alt="ofo破产?官方声明来了!" inline="0"><p class="pgc-img-caption">图片来源:网络</p></div><p class="ql-align-justify"> 数据仍在不断增加,有不少ofo用户被曝前往ofo北京总部(位于北京中关村的互联网金融中心)寻求退押金,现场排起了长队。</p><p class="ql-align-justify">ofo方面于去年12月17日晚推出新政:自2018年12月18日起,凡在App内提交线上申请退押金的用户,后台系统会根据申请提交的顺序进行相关信息审核与收集,核实完毕后用户将进入退押金序列,ofo将按顺序退款;如有线下登记的用户此前已经发起退款申请,则按此前的队列时间信息为准。</p><p class="ql-align-justify">ofo小黄车还提醒:由于用户基数大,存在退押金申请激增的可能。同时,ofo承诺依序妥善处理好退押金事宜。</p><p class="ql-align-justify">虽然做出了相关承诺,退押工作也在逐步推进,但用户仍忧心忡忡,担心万一ofo破产后拿不到押金。</p><h1 class="ql-align-center">招募区域化加盟代理商</h1><p class="ql-align-justify">为了给ofo续命化解经营危机,戴威也开始使用新的营销手段,比如招募ofo代理商。</p><p class="ql-align-justify">据钛媒体,ofo城市代理运营商主要负责辖区内ofo共享单车的运营业务,单车所有权仍归属于ofo公司,代理运营商只负责单车的维修、秩序维护等,ofo按照后台数据来结算费用。</p><p class="ql-align-justify">也就是说,ofo把原本属于各地分公司维护单车的任务外包了,负责维护的不再是自己员工,而是各地招募的代理商,此举可降低共享单车运营成本。</p><p class="ql-align-justify">为号召更多代理商加入,ofo宣称共享单车代理商已经成为一个新的热门行业。日前,据接近ofo内部人士透露,ofo今年将大范围向全国三、四线城市推广代理模式,此前,ofo曾在山东威海、泰安等城市试运行“代理”模式,而在代理商模式之前,ofo尝试过合伙人、直营+代理等模式,效果均不甚理想。如今,ofo小黄车遭遇前所未有的资金链危机,采取降低成本的运营方案就不难理解。</p><p class="ql-align-justify">ofo国内运营事业部总经理<span>周伟国</span>对此表示:“ofo进入精细化运营阶段,代理模式可将本土企业与行业巨头有效对接,既可实现引领行业快速发展,又能实现本土资源效率使用最大化,以最低的成本实现多赢发展。”</p><p class="ql-align-justify">此前,为给ofo续命,公司已不断开源节流,如在App上推出短视频广告,用户扫码骑行前需要观看短视频;比如官方微信公众号接受广告投放,甚至售卖三无蜂蜜并被人诟病;甚至为了免付用户押金而计划把用户导流给网贷企业,在正式推送后当天即宣告下线。</p><p class="ql-align-justify">而在宣布二三线城市开启代理运营商模式的前一天,ofo官方通报公司的反腐情况。经调查,ofo内部总共发生了8起腐败案件,其中4起已进入司法程序,5人被移送司法机关,涉案金额达数百万元,ofo也在积极追回账款。</p><p class="ql-align-justify">虽然使出浑身解数开源节流,但ofo是否能真的走出破产危机尚不太乐观。</p></div>"""
content = re.sub(r"<(?!/?\s?p|/?\s?img)[^<>]*>", "", content)   // 反向选择 去掉除了p和img之外的其他标签,可以在 | 后面在添加其他反向条件
content = re.sub(r"<p[\s\S]*?>", r"<p>", content)   // 替换p标签里面的style样式
# 分组替换 掉img标签里面的style样式, 但是保留img里面的src属性
# content = re.sub(r"<img[\s\S]*?src=[\"|\'](?P<src>[\s\S]*?)[\"|\'][\s\S]*?>", r"<img src=‘\g<src>’>", content)   # 方式一 这种是匹配src的链接
content = re.sub(r"<img[\s\S]*?(?P<src>src=[\"|\'][\s\S]*?[\"|\'])[\s\S]*?>", r"<img \g<src> >", content)   # 方式二  匹配整个src   \g是获取前面分组命名的固定写法
print(content)  
# 说个小技巧吧,应该大部分都知道,正则匹配的时候,可以先用repr(temp_str) 查看原始数据。  
# 输出  
"""<img src="http://p3.pstatp.com/large/pgc-image/adc1249ecb3140ec8e7037f37014c795" ><p></p><p>ofo回应破产传闻:消息严重不实,目前运营一切正常。此前新京报称,ofo运营主体拜克洛克首次现身全国...</p><p>本文来自全天候科技,阅读更多请登陆www.awtmt.com或华尔街见闻APP。</p><p>4月2日,全国企业破产重整案件信息网显示,ofo运营主体之一北京拜克洛克科技有限公司作为“被申请人”而出现,申请人为聂艳,日期是3月25日,办理法院为北京海淀区人民法院。多家媒体质疑ofo是否陷入破产危机。</p><p>下午,ofo回应破产传闻:消息严重不实,目前运营一切正常。此前新京报称,ofo运营主体拜克洛克首次现身全国破产信息网。</p><img src="http://p1.pstatp.com/large/pgc-image/84657696ee424b6399b4a5a992188d04" ><p></p><p>在此声明之前,ofo一直处于舆论的风口浪尖,从明星创业公司到濒临破产,ofo快速经历了这一切过程。</p>退押金风波<p>2018年12月中旬,ofo待退押金总额一再刷新。据全天候科技获悉,截至12月18日20时37分,排队退押用户数突破1000万。</p><p>ofo用户押金主要有99元与199元两种。如果以99元/位计算,保守估计,ofo需退还押金总额约10亿元;但若以199元/位计算,那么ofo需要退还高达近20亿元的押金。</p><img src="http://p3.pstatp.com/large/pgc-image/7c9fbdb6c3d1484d833cbfc4d55ad406" ><p>图片来源:网络</p><p> 数据仍在不断增加,有不少ofo用户被曝前往ofo北京总部(位于北京中关村的互联网金融中心)寻求退押金,现场排起了长队。</p><p>ofo方面于去年12月17日晚推出新政:自2018年12月18日起,凡在App内提交线上申请退押金的用户,后台系统会根据申请提交的顺序进行相关信息审核与收集,核实完毕后用户将进入退押金序列,ofo将按顺序退款;如有线下登记的用户此前已经发起退款申请,则按此前的队列时间信息为准。</p><p>ofo小黄车还提醒:由于用户基数大,存在退押金申请激增的可能。同时,ofo承诺依序妥善处理好退押金事宜。</p><p>虽然做出了相关承诺,退押工作也在逐步推进,但用户仍忧心忡忡,担心万一ofo破产后拿不到押金。</p>招募区域化加盟代理商<p>为了给ofo续命化解经营危机,戴威也开始使用新的营销手段,比如招募ofo代理商。</p><p>据钛媒体,ofo城市代理运营商主要负责辖区内ofo共享单车的运营业务,单车所有权仍归属于ofo公司,代理运营商只负责单车的维修、秩序维护等,ofo按照后台数据来结算费用。</p><p>也就是说,ofo把原本属于各地分公司维护单车的任务外包了,负责维护的不再是自己员工,而是各地招募的代理商,此举可降低共享单车运营成本。</p><p>为号召更多代理商加入,ofo宣称共享单车代理商已经成为一个新的热门行业。日前,据接近ofo内部人士透露,ofo今年将大范围向全国三、四线城市推广代理模式,此前,ofo曾在山东威海、泰安等城市试运行“代理”模式,而在代理商模式之前,ofo尝试过合伙人、直营+代理等模式,效果均不甚理想。如今,ofo小黄车遭遇前所未有的资金链危机,采取降低成本的运营方案就不难理解。</p><p>ofo国内运营事业部总经理周伟国对此表示:“ofo进入精细化运营阶段,代理模式可将本土企业与行业巨头有效对接,既可实现引领行业快速发展,又能实现本土资源效率使用最大化,以最低的成本实现多赢发展。”</p><p>此前,为给ofo续命,公司已不断开源节流,如在App上推出短视频广告,用户扫码骑行前需要观看短视频;比如官方微信公众号接受广告投放,甚至售卖三无蜂蜜并被人诟病;甚至为了免付用户押金而计划把用户导流给网贷企业,在正式推送后当天即宣告下线。</p><p>而在宣布二三线城市开启代理运营商模式的前一天,ofo官方通报公司的反腐情况。经调查,ofo内部总共发生了8起腐败案件,其中4起已进入司法程序,5人被移送司法机关,涉案金额达数百万元,ofo也在积极追回账款。</p><p>虽然使出浑身解数开源节流,但ofo是否能真的走出破产危机尚不太乐观。</p>"""

说个很方便的小技巧, 需要用到sublime编辑工具, (ps:在慕课网上学的)
比如爬虫会携带一大堆请求头数据,直接复制别人的header 需要自己手动一个个添加引号
1 打开sublime
2 粘贴请求头
3 按ctrl+h 组合键 注意需要开启正则模式才行 点击 .* 开启
4 点击 replace all 就好了

(.*?):\s(.*)      # Find  
"$1": "$2",     # Replace

在这里插入图片描述
转换之后就是这样的 不用手动添加引号 特别方便
在这里插入图片描述

简单图片识别

1 使用pytesseract 库简单图片识别 (不推荐,推荐使用下面那一种),

这种效果不是很好,复杂的情况建议直接打码平台。
注意:安装的时候有些小坑, 而且 chi_sim中文识别,这个库需要去github 上面下载地址。

from PIL import Image
import pytesseract
# 方式一 处理本地图片
im = Image.open("./aaa.png")
text = pytesseract.image_to_string(im, lang='chi_sim')   # 处理图片 lang是选择的语言,默认识别英文和数字
# 具体安装运行 可能有些坑, 
print(text)
# --------------------------------------------------
# 方式二 处理url图片字节流
import io
img2 = requests.get(url, headers=headers, stream=True)
byte_stream = io.BytesIO(img2.content)
img2_str = pytesseract.image_to_string(Image.open(byte_stream))
print(img2_str)
2 使用muggle_ocr库简单的验证码识别(推荐你用这个)

,效果比上面一种效率高,使用更方便,会自动安装tensorflow numpy这两个依赖库;
pip install muggle-ocr
https://pypi.org/project/muggle-ocr/

import time

# 1. 导入包
import muggle_ocr

"""
使用预置模型,预置模型包含了[ModelType.OCR, ModelType.Captcha] 两种
其中 ModelType.OCR 用于识别普通印刷文本, ModelType.Captcha 用于识别4-6位简单英数验证码

"""

# 打开印刷文本图片
with open(r"test1.png", "rb") as f:
    ocr_bytes = f.read()

# 打开验证码图片
with open(r"test2.jpg", "rb") as f:
    captcha_bytes = f.read()

# 2. 初始化;model_type 可选: [ModelType.OCR, ModelType.Captcha]
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)

# ModelType.Captcha 可识别光学印刷文本
for i in range(5):
    st = time.time()
    # 3. 调用预测函数
    text = sdk.predict(image_bytes=ocr_bytes)
    print(text, time.time() - st)

# ModelType.Captcha 可识别4-6位验证码
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.Captcha)
for i in range(5):
    st = time.time()
    # 3. 调用预测函数
    text = sdk.predict(image_bytes=captcha_bytes)
    print(text, time.time() - st)

"""
使用自定义模型
支持基于 https://github.com/kerlomz/captcha_trainer 框架训练的模型
训练完成后,进入导出编译模型的[out]路径下, 把[graph]路径下的pb模型和[model]下的yaml配置文件放到同一路径下。
将 conf_path 参数指定为 yaml配置文件 的绝对或项目相对路径即可,其他步骤一致,如下示例:
"""
with open(r"test3.jpg", "rb") as f:
    b = f.read()
sdk = muggle_ocr.SDK(conf_path="./ocr.yaml")
text = sdk.predict(image_bytes=b)

检测代理IP是否有效

代理IP,每个爬虫人员多少都会用到一点的,检测代理IP的方式也有很多种,这只是其中之一

import telnetlib

# 连接Telnet服务器
try:
	# 参数说明                   ip             端口        超时时间 
    tn = telnetlib.Telnet('115.227.159.73', port='4312', timeout=10)   
except Exception as e:
    print('失败', e)
else:
    print('成功')

Linux 定时任务篇

有时候我需要去定时之前的爬虫数据。
定时任务在Ubuntu系发行版和 Cetntos系上,操作稍微有点不一样, 总体是一样的。
定时任务的重要性,引用下下面网站的一句话:Cron job failures can be disastrous!

crontab -e   # 进入定时任务编辑界面
# 就可以进入编辑界面 用法和Vi编辑器差不多  # Ubuntu上或许第一进入会让你选择用什么编辑器 我现在只记得选择的第三种
# 可以写你的定时任务脚本了 
# 可参考 https://crontab.guru/
ctrl+O  # 回车 Enter 确认定时任务文件名
ctrl+X  # 保存退出

# 写完之后 最好重启下
写完一个定时任务命令之后需要重启,下面是相关的操作语句。
注意不同发行版的不同 参考链接  https://www.cyberciti.biz/faq/howto-linux-unix-start-restart-cron/
# Debian/Ubuntu/Linux EXamples:
sudo service cron status   
sudo service cron stop
sudo service cron start
sudo service cron restart
# RHEL/CentOS/Fedor Linux:
service crond status
service crond stop
service crond start
service crond restart

如果报:Redirecting to /bin/systemctl start  crond.service
估计是使用的是Centos7或者Fedora高版本,启用服务变化了。
就执行:
systemctl restart crond.service
# 查看你现在正在执行中的定时任务
crontab -l

Linux后台运行Python文件

有时候,写了一些小脚本,就一个py文件写的,需要丢到服务器让它慢慢跑,这时就需要后台运行了,然后关于命令 2>&1的解释,我搜了下StackOverflow上面的解释 ,有兴趣可以了解了解https://stackoverflow.com/questions/818255/in-the-shell-what-does-21-mean 如果这个网站访问慢打不开,参考我之前转载博客可以解决。

# nohup 命令可能需要安装
# 后台运行  表示不挂起(no hang up)  使用-u参数,使得python不启用缓冲
nohup python -u test.py > test.log 2>&1 &

另外补充一个,kill指定端口的命令()

# kill 占用端口号为8080的程序
kill -9 `lsof -t -i:8080`

关于 requests 库的操作

  • cookies的用法
# 使用cookie的话,我就推荐用requests的姊妹库requests_html, 对cookie操作更友好
from requests_html import HTMLSession
session = HTMLSession()  # 使用方法和requests一样(因为都是kennethreitz写的)
res = session.get("http://www.baidu.com")
dict_current_cookie = session.cookies.get_dict()   # dict类型的cookie
print(dict_current_cookie)  # 可以把cookie保存到redis之类的地方

# 加载使用 cookie 我是使用的这种笨办法, 重新把格式重组的
old_cookie = ";".join([f"{i}={dict_current_cookie[i]}" for i in dict_current_cookie])

s = session.get(example_url, cookies=old_cookie)
  • 请求媒体资源文件,比如小视频,音乐,图片等
import requests
 
with requests.get("http://xxx.xxx.com/xxxx.mp4", stream=True) as req:
    with open("./test_name.mp4", "wb+") as f:
        f.write(req.content)

验证requests http请求

比如验证代理,请求头是否有效, 可以使用这个网站 https://httpbin.org

GET请求验证 https://httpbin.org/get

import requests
headers = {
   "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
}
proxies = {
    "http": "http://115.207.115.83:4376",
    "https": "http://115.207.115.83:4376"
}
url = "https://httpbin.org/get"
resp = requests.get(url, headers=headers, proxies=proxies)
print(resp.status_code)
print(resp.text)

输出

200
{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-5fd426e7-68c54eb72581379373f3038b"
  }, 
  "origin": "115.207.115.83", 
  "url": "https://httpbin.org/get"
}

POST请求测试 https://httpbin.org/post

url = "https://httpbin.org/post"
json_data = {
    "qqq": ["1111", "222"],
    "www": {"qq": "zz"}
}
resp = requests.post(url, json=json_data, headers=headers)
print(resp.json())

返回

{
  "args": {}, 
  "data": "{\"qqq\": [\"1111\", \"222\"], \"www\": {\"qq\": \"zz\"}}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "45", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36", 
    "X-Amzn-Trace-Id": "Root=1-5fd429b1-75fd90d55f44a03653698acc"
  }, 
  "json": {
    "qqq": [
      "1111", 
      "222"
    ], 
    "www": {
      "qq": "zz"
    }
  }, 
  "origin": "你的IP", 
  "url": "https://httpbin.org/post"
}


  • 未完待续....
posted @ 2020-04-03 16:05  王小右  阅读(254)  评论(0编辑  收藏  举报