100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > python爬虫之ip代理参数/动态加载数据抓取

python爬虫之ip代理参数/动态加载数据抓取

时间:2023-12-07 01:39:40

相关推荐

python爬虫之ip代理参数/动态加载数据抓取

文章目录

前情回顾requests.get()参数常见的反爬机制及处理方式今日笔记代理参数-proxies控制台抓包requests.post()参数有道翻译破解案例(post)python中正则处理headers和formdata民政部网站数据抓取动态加载数据抓取-Ajax豆瓣电影数据抓取案例今日任务

前情回顾

requests.get()参数

1、url2、params -> {} :查询参数 Query String3、proxies -> {}proxies = {'http':'http://1.1.1.1:8888','https':'https://1.1.1.1:8888'}4、auth -> ('tarenacode','code_')5、verify -> True/False6、timeout

常见的反爬机制及处理方式

1、Headers反爬虫 :Cookie、Referer、User-Agent解决方案: 通过F12获取headers,传给requests.get()方法2、IP限制 :网站根据IP地址访问频率进行反爬,短时间内限制IP访问解决方案: 1、构造自己IP代理池,每次访问随机选择代理,经常更新代理池2、购买开放代理或私密代理IP3、降低爬取的速度3、User-Agent限制 :类似于IP限制解决方案: 构造自己的User-Agent池,每次访问随机选择4、对响应内容做处理解决方案: 打印并查看响应内容,用xpath或正则做处理

今日笔记

代理参数-proxies

定义

1、定义: 代替你原来的IP地址去对接网络的IP地址。2、作用: 隐藏自身真实IP,避免被封。

普通代理

获取代理IP网站

西刺代理、快代理、全网代理、代理精灵、... ...

参数类型

1、语法结构proxies = {'协议':'协议://IP:端口号'}2、示例proxies = {'http':'http://IP:端口号','https':'https://IP:端口号'}

示例

使用免费普通代理IP访问测试网站: /get

import requestsurl = '/get'headers = {'User-Agent':'Mozilla/5.0'}# 定义代理,在代理IP网站中查找免费代理IPproxies = {'http':'http://112.85.164.220:9999','https':'https://112.85.164.220:9999'}html = requests.get(url,proxies=proxies,headers=headers,timeout=5).textprint(html)

思考: 建立一个自己的代理IP池,随时更新用来抓取网站数据

1、从西刺代理IP网站上,抓取免费代理IP2、测试抓取的IP,可用的保存在文件中

思考 - 代码实现

import requestsurl="/nn/"# url="/nn/"proxies={"http":"http://309435365:szayclhp@222.89.74.38:17714","https":"https://309435365:szayclhp@222.89.74.38:17714"}headers = {'User-Agent':'Mozilla/5.0' }html=requests.get(url=url,headers=headers,proxies=proxies).textprint(html)

私密代理

语法格式

1、语法结构proxies = {'协议':'协议://用户名:密码@IP:端口号'}2、示例proxies = {'http':'http://用户名:密码@IP:端口号','https':'https://用户名:密码@IP:端口号'}

示例代码

import requestsurl = '/get'proxies = {'http':'http://309435365:szayclhp@1.195.160.232:17509','https':'https://309435365:szayclhp@1.195.160.232:17509'}headers = {'User-Agent' : 'Mozilla/5.0',}html = requests.get(url,proxies=proxies,headers=headers,timeout=5).textprint(html)

控制台抓包

打开方式及常用选项309435365@zhanshen001

1、打开浏览器,F12打开控制台,找到Network选项卡2、控制台常用选项1、Network: 抓取网络数据包1、ALL: 抓取所有的网络数据包2、XHR:抓取异步加载的网络数据包3、JS : 抓取所有的JS文件2、Sources: 格式化输出并打断点调试JavaScript代码,助于分析爬虫中一些参数3、Console: 交互模式,可对JavaScript中的代码进行测试3、抓取具体网络数据包后1、单击左侧网络数据包地址,进入数据包详情,查看右侧2、右侧:1、Headers: 整个请求信息General、Response Headers、Request Headers、Query String、Form Data2、Preview: 对响应内容进行预览3、Response:响应内容

requests.post()参数

适用场景

Post类型请求的网站

参数-data

response = requests.post(url,data=data,headers=headers)# data :post数据(Form表单数据-字典格式)

请求方式的特点

# 一般GET请求 : 参数在URL地址中有显示POST请求: Form表单提交数据

有道翻译破解案例(post)

目标

破解有道翻译接口,抓取翻译结果# 结果展示请输入要翻译的词语: elephant翻译结果: 大象**************************请输入要翻译的词语: 喵喵叫翻译结果: mews

实现步骤

1、浏览器F12开启网络抓包,Network-All,页面翻译单词后找Form表单数据2、在页面中多翻译几个单词,观察Form表单数据变化(有数据是加密字符串)3、刷新有道翻译页面,抓取并分析JS代码(本地JS加密)4、找到JS加密算法,用Python按同样方式加密生成加密数据5、将Form表单数据处理为字典,通过requests.post()的data参数发送

具体实现

1、开启F12抓包,找到Form表单数据如下:

i: 喵喵叫from: AUTOto: AUTOsmartresult: dictclient: fanyideskwebsalt: 15614112641250sign: 94008208919faa19bd531acde36aac5dts: 1561411264125bv: f4d62a2579ebb44874d7ef93ba47e822doctype: jsonversion: 2.1keyfrom: fanyi.webaction: FY_BY_REALTlME

2、在页面中多翻译几个单词,观察Form表单数据变化

salt: 15614112641250sign: 94008208919faa19bd531acde36aac5dts: 1561411264125bv: f4d62a2579ebb44874d7ef93ba47e822# 但是bv的值不变

3、一般为本地js文件加密,刷新页面,找到js文件并分析JS代码

# 方法1Network - JS选项 - 搜索关键词salt# 方法2控制台右上角 - Search - 搜索salt - 查看文件 - 格式化输出# 最终找到相关JS文件 : fanyi.min.js

4、打开JS文件,分析加密算法,用Python实现

# ts : 经过分析为13位的时间戳,字符串类型js代码实现: "" + (new Date).getTime()python实现: str(int(time.time()*1000))# saltjs代码实现: ts+parseInt(10 * Math.random(), 10);python实现: ts+str(random.randint(0,9))# sign(设置断点调试,来查看 e 的值,发现 e 为要翻译的单词)js代码实现: n.md5("fanyideskweb" + e + salt + "n%A-rKaT5fb[Gy?;N5@Tj")python实现:from hashlib import md5string=""s=md5()s.update(string.encode())sign=s.hexdigest()

5、代码实现

import requests, time, randomfrom hashlib import md5from day01.User_Agent import getheadersclass YouDao:def __init__(self):# url一定要写F12抓到的post的地址self.url = '/translate_o?smartresult=dict&smartresult=rule'self.headers = {# "Accept":"application/json, text/javascript, */*; q=0.01",# "Accept-Encoding":"gzip, deflate",# "Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8",# "Connection":"keep-alive",# "Content-Length":"239",# "Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","Cookie": "P_INFO=xinwei_user; OUTFOX_SEARCH_USER_ID=1087533395@10.169.0.83; JSESSIONID=aaay3E4LlPWDr64vjDn3w; OUTFOX_SEARCH_USER_ID_NCOO=1784198643.0122821; ___rl__test__cookies=157113178",# "Host":"",# "Origin":"","Referer": "/","User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36",# "X-Requested-With":"XMLHttpRequest",}# self.proxies={}# 获取ts,salt,signdef get_ts_salt_sign(self, word):ts = str(random.randint(0, 9))salt = ts + str(int(time.time() * 1000))string = "fanyideskweb" + word + salt + "n%A-rKaT5fb[Gy?;N5@Tj"s = md5()s.update(string.encode())sign = s.hexdigest()return ts, salt, signdef attack(self, word):ts, salt, sign = self.get_ts_salt_sign(word)# form表单数据data = {"i": word,"from": "AUTO","to": "AUTO","smartresult": "dict","client": "fanyideskweb","salt": salt,"sign": sign,# "ts": ts,# "bv": "65313ac0ff6808a532a1d4971304070e","doctype": "json","version": "2.1","keyfrom": "fanyi.web","action": "FY_BY_REALTlME", }# 此处为post请求,一定使用requests.post# html=requests.post(#url=self.url,#data=data,#headers=self.headers,## proxies=self.proxies# ).text #返回值为字符串html = requests.post(url=self.url,data=data,headers=self.headers,# proxies=self.proxies).json()# print(type(html),html) #返回值为字典print("翻译结果:", html["translateResult"][0][0]["tgt"])# print(html)def run(self):word = input("请输入单词:")self.attack(word)if __name__ == '__main__':y = YouDao()y.run()

python中正则处理headers和formdata

1、pycharm进入方法 :Ctrl + r ,选中 Regex2、处理headers和formdata(.*): (.*)"$1": "$2",3、点击 Replace All

民政部网站数据抓取

目标

1、URL: http://www./ - 民政数据 - 行政区划代码即: http://www./article/sj/xzqh//2、目标: 抓取最新中华人民共和国县以上行政区划代码

实现步骤

1、从民政数据网站中提取最新行政区划代码链接

# 特点1、最新的在上面2、命名格式: X月中华人民共和国县以上行政区划代码#a_list:[<element a at xxx]a_list=p.xpath('a[@class="artitlelist"]')for a in a_list:title=a.get("title")if title.endswith("行政区快代码")#第一个满足条件的一定是最新的文章链接href=a.get("href")break

2、从二级页面链接中提取真实链接(反爬-响应内容中嵌入JS,指向新的链接)

1、向二级页面链接发请求得到响应内容,并查看嵌入的JS代码2、正则提取真实的二级页面链接

3、真实链接中提取所需数据

4、代码实现

import reimport requestsfrom lxml import etreefrom day01.User_Agent import getheadersclass MinZheng:def __init__(self):self.url = 'http://www./article/sj/xzqh//'self.headers = getheaders()# 获取最新链接def get_link(self):one_html = requests.get(url=self.url, headers=self.headers).text# xpath提取最新链接p = etree.HTML(one_html)link_list = p.xpath('//table//tr[2]/td[2]/a/@href')link = link_list[0] if link_list else Noneif link:link = 'http://www./article/sj/xzqh//' + ("/").join(link.split("/")[-2:])#http://www./article/sj/xzqh//09/0900019994.shtml 非真实链接print(link)self.parse_html(link)else:print("链接提取失败!")# 提取数据def parse_html(self, link):two_html = requests.get(url=link, headers=self.headers).text#保存跳转页面with open('cccz.html',"w") as f:f.write(two_html)p = etree.HTML(two_html)new1_html = p.xpath('//script/text()')[0]# print(new1_html)#提取跳转链接new2_html=re.findall('window.location.href="(.*?)"',new1_html)[0]# print(new2_html)two_new_html=requests.get(url=new2_html,headers=self.headers).textp = etree.HTML(two_new_html)tr_list = p.xpath('//tr[@height="19"]')for tr in tr_list:name = tr.xpath('./td[3]/text()')[0].strip()code = tr.xpath('./td[2]/text()')[0].strip()print(name, code)# 入口函数def run(self):self.get_link()if __name__ == '__main__':m = MinZheng()m.run()

扩展

1、建立增量爬虫 - 网站有更新时抓取,否则不抓(设置指纹函数)2、所抓数据存到数据库,按照层级关系分表存储 - 省、市、县表

动态加载数据抓取-Ajax

特点

1、右键 -> 查看网页源码中没有具体数据2、滚动鼠标滑轮或其他动作时加载,或者页面局部刷新,页面才能加载出来

抓取

1、F12打开控制台,页面动作抓取网络数据包2、抓取json文件URL地址# 控制台中 XHR :异步加载的数据包# XHR -> QueryStringParameters(查询参数)

豆瓣电影数据抓取案例

目标

1、地址: 豆瓣电影 - 排行榜 - 剧情2、目标: 电影名称、电影评分

F12抓包(XHR)

1、Request URL(基准URL地址) :/j/chart/top_list?2、Query String(查询参数)# 抓取的查询参数如下:type: 13 # 电影类型interval_id: 100:90action: ''start: 0 # 每次加载电影的起始索引值 0 20 40 60 limit: 20 # 每次加载的电影数量

代码实现 - 全站抓取 - 完美接口 - 指定类型所有电影信息

import reimport requests, jsonfrom fake_useragent import UserAgentclass DouBan:def __init__(self):self.url = "/j/chart/top_list?"self.i = 1def parse_html(self, params):html = requests.get(url=self.url,params=params,headers={"User-Agent": UserAgent().random}).text# json.loads():json数据->python数据类型html = json.loads(html)# print(html)item = {}for film in html:item["name"] = film["title"]item["score"] = film["score"]self.i += 1print(item)def run(self):type_dic = self.get_name_type()name = input("\n请输入类型:")typ = type_dic[name]totle = self.get_totle(typ)for page in range(0, totle, 20):params = {"type": typ,"interval_id": "100:90","action": "","start": str(page),"limit": "20"}self.parse_html(params)print(self.i)def get_totle(self, typ):url = '/j/chart/top_list_count?type={}&interval_id=100%3A90'.format(typ)html = requests.get(url=url, headers={"User-Agent": UserAgent().random}).json()totle = html["total"]return totledef get_name_type(self):url = '/chart'html = requests.get(url=url, headers={"User-Agent": UserAgent().random}).textp = pile('<a.*?type_name=(.*?)&type=(.*?)&interval_id.*?</a>', re.S)r_list = p.findall(html)type_dict = {}print("电影类型:")for r in r_list:type_dict[r[0]] = r[1]print(r[0],end=" ")return type_dictif __name__ == '__main__':d = DouBan()d.run()

今日任务

1、有道翻译案例复写一遍2、抓取腾讯招聘数据(两级页面 - 职位名称、岗位职责、工作要求)3、抓取百度图片 - 所有,而不是30张4、民政部数据抓取案例完善# 1、将抓取的数据存入数据库,最好分表按照层级关系去存# 2、增量爬取时表中数据也要更新

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。