需求文档的定制
糗事百科的段子内容和作者(xpath的管道符)名称进行爬取,然后存储到mysql中or文本
http://sc.chinaz.com/jianli/free.html爬取简历模板 HTTPConnectionPool(host:XX)Max retries exceeded with url。
原因:
1.当你在短时间内发起高频请求的时候,http的连接池中的连接资源被耗尽。
Connection:keep-alive
2.ip被封
解决:
Connection:'close'
爬取一个你感兴趣的网站数据

数据解析
目的:实现聚焦爬虫!!!
数据解析的通用原理:
1.标签定位
2.数据提取
bs4:
1.实例化一个BeautifulSoup的对象,将即将被解析的页面源码加载到该对象
2.属性和方法实现标签定位和数据的提取
soup.tagName
soup.find/find_all('tagName',class_='value')
select('选择器'):返回的是列表
tag.text/string:字符串
tag['attrName']
xpath:xpath方法返回的一定是列表
表达式最左侧的/ 和 //的区别
非最左侧的/和//的区别
属性定位://div[@class="xxx"]
索引定位://div[2]
/text() //text()
/div/a/@href
 
  • 代理操作
  • cookie的操作
  • 验证码的识别
  • 模拟登陆
 
代理操作
目的:为解决ip被封的情况
什么是代理?
代理服务器:fiddler
为什么使用了代理就可以更改请求对应的ip呢?
本机的请求会先发送给代理服务器,代理服务器会接受本机发送过来的请求(当前请求对应的ip就是本机ip),然后代理服务器会将该请求进行转发,转发之后的请求对应的ip就是代理服务器的ip。
提供免费代理ip的平台
www.goubanjia.com
快代理
西祠代理
代理精灵:http://http.zhiliandaili.cn
代理ip的匿名度 透明:使用了透明的代理ip,则对方服务器知道你当前发起的请求使用了代理服务器并且可以监测到你真实的ip
匿名:知道你使用了代理服务器不知道你的真实ip
高匿:不知道你使用了代理服务器也不知道你的真实ip
代理ip的类型 http:该类型的代理IP只可以转发http协议的请求
https:只可以转发https协议的请求
 
 
 
#代理测试
import requests
from lxml import etree
import random
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
​ #构建一个简易的ip池
proxy_list = [
{'https':'212.64.51.13:8888'},
{'https':'212.64.51.13:8888'},
{'https':'212.64.51.13:8888'},
] url = 'https://www.baidu.com/s?ie=UTF-8&wd=ip'
#proxies指定代理ip
page_text = requests.get(url=url,headers=headers,proxies=random.choice(proxy_list)).text
with open('ip.html','w',encoding='utf-8') as fp:
fp.write(page_text)
 
 
如何构建一个标准的代理ip池    (goubanjia    代理精灵    )
1.取各大平台中爬取大量的免费代理ip
2.校验出可用的代理ip
使用每一个代理ip进行请求发送,监测响应状态码是否为200
3.将可用的代理ip进行存储(redis) all_ips = []
ip_url = 'http://ip.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=53&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson='
page_text = requests.get(ip_url,headers=headers).text
tree = etree.HTML(page_text)
ip_list = tree.xpath('//body//text()')
for ip in ip_list:
ip = {'https':ip}
all_ips.append(ip) In [29]: url = 'https://www.xicidaili.com/nn/%d'
for page in range(1,100):
print('正在爬取第{}页的数据!'.format(page))
new_url = format(url%page)
page_text = requests.get(url=new_url,headers=headers,proxies=random.choice(all_ips)).text
tree = etree.HTML(page_text)
tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:]
for tr in tr_list:
ip = tr.xpath('./td[2]/text()')[0]
port = tr.xpath('./td[3]/text()')[0]
ip_type = tr.xpath('./td[6]/text()')[0]
dic = {
'ip':ip,
'port':port,
'type':ip_type
}
all_ips.append(dic)
print(len(all_ips))
 
 
  • Cookie

    • 什么是cookie?

      • 保存在客户端的键值对
  • 爬取雪球网中的新闻数据:https://xueqiu.com/
 
 
 
 
 
#通过抓包工具捕获的基于ajax请求的数据包中提取的url
url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20343389&count=15&category=-1'
json_data = requests.get(url=url,headers=headers).json()
print(json_data)
​ {'error_description': '遇到错误,请刷新页面或者重新登录帐号后再试', 'error_uri': '/v4/statuses/public_timeline_by_category.json', 'error_data': None, 'error_code': ''} cookie的破解方式
手动处理:
通过抓包工具将请求携带的cookie添加到headers中
弊端:cookie会有有效时长,cookie还是动态变化
自动处理:
使用session进行cookie的自动保存和携带
session是可以进行请求发送的,发送请求的方式和requests一样
如果使用session进行请求发送,在请求的过程中产生了cookie,则该cookie会被自动存储到session对象中
如果使用了携带cookie的session再次进行请求发送,则该次请求就时携带cookie进行的请求发送 #创建一个session对象
session = requests.Session()
#将cookie保存到session对象中
first_url = 'https://xueqiu.com/'
session.get(url=first_url,headers=headers)#为了获取cookie且将cookie存储到session中

url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20343389&count=15&category=-1'
json_data = session.get(url=url,headers=headers).json()#携带cookie发起的请求
json_data
. . .
 
 
 
 
 
 
import requests
from hashlib import md5

class Chaojiying_Client(object):

def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}

def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()

def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
def getCodeImgText(imgPath,imgType):

    chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370')#用户中心>>软件ID 生成一个替换 96001

    im = open(imgPath, 'rb').read()#本地图片文件路径 来替换 a.jpg 有时WIN系统须要//

    return chaojiying.PostPic(im,imgType)['pic_str']
 
 
 
 
 

#古诗文网的验证码识别操作
url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
page_text = requests.get(url,headers=headers).text
tree = etree.HTML(page_text)
img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0]
print(img_src)
img_data = requests.get(url=img_src,headers=headers).content
with open('codeImg.jpg','wb') as fp:
fp.write(img_data)
#进行验证码的识别
getCodeImgText('codeImg.jpg',1004) https://so.gushiwen.org/RandCode.ashx 'abt9'
 
 
 
 

s = requests.Session()
#模拟登陆
#古诗文网的验证码识别操作
url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
page_text = s.get(url,headers=headers).text
tree = etree.HTML(page_text)
img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0]
img_data = s.get(url=img_src,headers=headers).content
with open('codeImg.jpg','wb') as fp:
fp.write(img_data)
#解析动态变化的请求参数
__VIEWSTATE = tree.xpath('//input[@id="__VIEWSTATE"]/@value')[0]
__VIEWSTATEGENERATOR = tree.xpath('//input[@id="__VIEWSTATEGENERATOR"]/@value')[0]
print(__VIEWSTATE,__VIEWSTATEGENERATOR)
#进行验证码的识别
code_text = getCodeImgText('codeImg.jpg',1004)
print(code_text)
login_url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
data = {
#下面两个请求参数是动态变化
#通长情况下动态变化的请求参数会被隐藏在前台页面中
'__VIEWSTATE': __VIEWSTATE,
'__VIEWSTATEGENERATOR': __VIEWSTATEGENERATOR,
'from': 'http://so.gushiwen.org/user/collect.aspx',
'email': 'www.zhangbowudi@qq.com',
'pwd': 'bobo328410948',
'code': code_text,
'denglu': '登录',
}
#登陆成功之后对应的首页页面源码
main_page_text = s.post(url=login_url,headers=headers,data=data).text
with open('./main.html','w',encoding='utf-8') as fp:
fp.write(main_page_text) bYMP3RE7FaZbXTvLHv5jqvU+oBFf724TXFoNPnly3qgtvK1IuW803mee/rn7QSnnThGZKU/Xx0PsTcksCzRzv6kE1l1FN3W+2lev+CzshULLoDTndVVDOQcl4mk= C93BE1AE
5zz8 反爬机制
cookie
动态变化的请求参数
验证码
代码
标记
原生 NBConvert
标题
-

 
 
In [2]:
 
 
 
 
 
import requests
import time
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'
}
 
 
 

同步代码

 
  • flask服务器代码:
In [ ]:
 
 
 
 
 
from flask import Flask
from time import sleep
app = Flask(__name__)
@app.route('/bobo')
def index1():
    sleep(2)
    return 'hello bobo!'
@app.route('/jay')
def index2():
    sleep(2)
    return 'hello jay!'
@app.route('/tom')
def index3():
    sleep(2)
    return 'hello tom!'
app.run()
 
 
In [ ]:
 
 
 
 
 
 
 
In [3]:
 
 
 
 
 
start = time.time()
urls = [
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom',
]
for url in urls:
    page_text = requests.get(url,headers=headers).text
    print(page_text)

print(time.time()-start)

 
 
 
hello bobo!
hello jay!
hello tom!
6.016878366470337
 

基于线程池实现异步爬取

from multiprocessing.dummy import Pool #线程池模块
#必须只可以有一个参数
def my_requests(url):
    return requests.get(url=url,headers=headers).text
start = time.time()
urls = [
    'http://127.0.0.1:5000/bobo',
    'http://127.0.0.1:5000/jay',
    'http://127.0.0.1:5000/tom',
]
pool = Pool(3)
#map:两个参数
#参数1:自定义的函数,必须只可以有一个参数
#参数2:列表or字典
#map的作用就是让参数1表示的自定义的函数异步处理参数2对应的列表或者字典中的元素
page_texes = pool.map(my_requests,urls)
print(page_texes)
print(time.time()-start)
['hello bobo!', 'hello jay!', 'hello tom!']
2.0126171112060547
 
  • asyncio

    • 如何产生一个携程对象
    • 什么是任务对象
    • 任务对象和携程对象的区别
    • 任务对象如何绑定一个回调呢
    • 什么是事件循环呢?
  • aiohttp

爬虫之 cookie , 验证码,模拟登陆,线程的更多相关文章

  1. 爬虫入门之scrapy模拟登陆(十四)

    注意:模拟登陆时,必须保证settings.py里的COOKIES_ENABLED(Cookies中间件) 处于开启状态 COOKIES_ENABLED = True或# COOKIES_ENABLE ...

  2. 利用selenium库自动执行滑动验证码模拟登陆

    破解流程 #1.输入账号.密码,然后点击登陆 #2.点击按钮,弹出没有缺口的图 #3.针对没有缺口的图片进行截图 #4.点击滑动按钮,弹出有缺口的图 #5.针对有缺口的图片进行截图 #6.对比两张图片 ...

  3. Python爬虫学习笔记之模拟登陆并爬去GitHub

    (1)环境准备: 请确保已经安装了requests和lxml库 (2)分析登陆过程:     首先要分析登陆的过程,需要探究后台的登陆请求是怎样发送的,登陆之后又有怎样的处理过程.      如果已经 ...

  4. python爬虫学习(3)_模拟登陆

    1.登陆超星慕课,chrome抓包,模拟header,提取表单隐藏元素构成params. 主要是验证码图片地址,在js中发现由js->new Date().getTime()时间戳动态生成url ...

  5. Go -- client 302 自动转 200 问题 cookie存储 模拟登陆问题

    不久前用go写了个http client,去模拟某网站(*.com)的登录操作.网站的登录逻辑:1.验证登录账号和密码:2.下发token.此token通过cookie下发:3.redirect到主页 ...

  6. Python爬虫教程:requests模拟登陆github

    1. Cookie 介绍 HTTP 协议是无状态的.因此,若不借助其他手段,远程的服务器就无法知道以前和客户端做了哪些通信.Cookie 就是「其他手段」之一. Cookie 一个典型的应用场景,就是 ...

  7. 破解验证码模拟登陆cnblogs

    from selenium import webdriver from selenium.webdriver import ActionChains from PIL import Image imp ...

  8. Python模拟登陆新浪微博

    上篇介绍了新浪微博的登陆过程,这节使用Python编写一个模拟登陆的程序.讲解与程序如下: 1.主函数(WeiboMain.py): import urllib2 import cookielib i ...

  9. 通过cookies信息模拟登陆

    import requests # 这个练习演示的是通过传入cookie信息模拟登陆,这样操作的前提是需要预先在浏览器登陆账户抓包得到cookie字段信息 url = "http://www ...

随机推荐

  1. 009.MFC_Spin

    数值调节按钮CSpinButtonCtrl属性 Alignment Auto Buddy Set Buddy integer成员函数 SetRange32() SetBase()

  2. pytorch torch.Stroage();torch.cuda()

    转自:https://ptorch.com/news/52.html torch.Storage是单个数据类型的连续的一维数组,每个torch.Tensor都具有相同数据类型的相应存储.他是torch ...

  3. 第二阶段:2.商业需求分析及BRD:1.产品需求管理

    产品经理需要投入大量的时间在需求方面的工作. 一张图看出需求多么重要.各个方面的人物对需求的误解导致的后果. 首先收集需求 需求采集 可以用excel收集数据并整理 备注信息也很重要 有时候要跟提出人 ...

  4. C# 字符串与二进制的相互转换

    /// <summary> /// 将字符串转成二进制 /// </summary> /// <param name="s"></para ...

  5. iptables详细参数讲解

    table 表 --> chain 链 --->rule 规则Commands:Either long or short options are allowed. --append -A ...

  6. 斜率优化入门题题单$QwQ$

    其实就是这一篇的那个例题帕的大部分题目的题解就写这儿辣,,, 因为都是些基础题不想专门给写题解,,,但是又掌握得差不得不写,,, 麻油办法就写一块儿好辣$QwQ$ 当然辣比较难的我就没放进来辣$QwQ ...

  7. JDK1.8的HashMap实现原理和源码解析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构.许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,本文会对java集合框架中的对应实现HashMap的 ...

  8. Spring MVC 请求处理过程

    1.  2. 3. 4. 5. 6.

  9. Qt5学习(1)

    1. In Qt, if you want to apply styles to the main window  itself, you must apply it to  its central ...

  10. PHP高级程序员必看知识点:目录大全(不定期更新)

    面试题系列: 分享一波腾讯PHP面试题 2019年PHP最新面试题(含答案) Redis 高级面试题 学会这些还怕进不了大厂? 阿里面试官三年经验PHP程序员知识点汇总,学会你就是下一个阿里人! ph ...