python爬虫基础二

上一篇博客中我们有提到,经过python爬虫去爬取服务器端的代码可能会被服务器阻拦,所以,我们要有措施来应对阻碍我们前进的障碍。
当我们用python访问的时候,hearder中的User-Agent会显示python+版本号,我们可以通过修改它的值来达到隐藏的效果。

在python爬虫基础一的博客中我们谈到爬取有道翻译的过程,在这个例子中我们加入隐藏字段:

head = {}
head['User-Agent'] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"

其中,User-Agent的内容即网页中的User-Agent,这样修改之后的结果并没有变化,但我们在爬取服务器时可以隐藏代码访问的痕迹。

还有一种方法,使用add_header将User-Agent的内容追加进去。

req = urllib.request.Request(url,data)
req.add_header('User-Agent',"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36")

完整代码如下:

import json
import urllib.request
import urllib.parse

content = input('请输入需要翻译的内容:')
url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'

#head = {}
#head['User-Agent'] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36"

data = {}
data['i'] =  content
data['from'] = 'AUTO'
data['to'] =  'AUTO'
data['smartresult'] = 'dict'
data['client']= 'fanyideskweb'
data['salt'] = '1522810548560'
data['sign']  = '1c3052fed220e88ca910ac44dedd91ea'
data['doctype'] = 'json'
data['version']  = '2.1'
data['keyfrom']  = 'fanyi.web'
data['action']  = 'FY_BY_REALTIME'
data['typoResult']  = 'false'

data = urllib.parse.urlencode(data).encode('utf-8')

#req = urllib.request.Request(url,data,head)
req = urllib.request.Request(url,data)
req.add_header('User-Agent',"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36")

response = urllib.request.urlopen(url,data)
html = response.read().decode('utf-8')

#print(html)
target = json.loads(html)
print('翻译结果 %s' % (target['translateResult'][0][0]['tgt']))

当我们使用爬虫爬取网页图片的时候,服务器可以通过记录每个IP地址的访问频率来判断是否四爬虫,因此我们需要来模拟是正常人类在访问。有两种方法,一种是延迟访问时间,一种是使用代理。

第一种,引入time模块,使用sleep函数。

 time.sleep(2)

但是延时处理的弊端就是会比较慢,我们也可以使用代理:
1,参数是一个字典{‘类型’:‘代理IP:端口号’}

proxy_support = urllib.request.ProxyHandler({})

2,定制创建一个opener

opener = urllib.request.build_opener(proxy_support)

3,a,安装opener(一劳永逸)

urllib.request.install_opener(opener)

b,调用opener(方便一时使用)

opener.open(url)
import urllib.request

url = "http://www.whatismyip.com.tw"
proxy_support = urllib.request.ProxyHandler({'http':'58.240.53.196:8080'})
opener = urllib.request.build_opener(proxy_support)
urllib.request.install_opener(opener)

response = urllib.request.urlopen(url)
html = response.read().decode('utf-8')

print(html)

这里有很详细的一篇关于爬取妹子图的博客
戳链接写给小白看的爬虫系列之爬虫入门爬取妹子图

### 如何使用二叉树存储数学表达式 二叉树是一种非常适合用于表示数学表达式的数据结构,因为其天然支持操作符和操作数之间的层次关系。以下是关于如何用二叉树存储数学表达式的具体方法及其实现。 #### 表达式二叉树的概念 表达式二叉树是一个特殊的二叉树,其中叶子节点代表操作数(如数字),而非叶节点则代表操作符(如加减乘除)。这种结构能够清晰地展示表达式的计算顺序以及运算符的优先级[^1]。 #### 构建表达式二叉树的方式 可以通过三种主要方式构建表达式二叉树:前缀表达式、中缀表达式和后缀表达式。每种方式都有对应的算法来解析并生成二叉树。 ##### 前缀表达式构建二叉树 前缀表达式是以操作符开头的形式书写表达式。例如,“+ 3 4”。要从前缀表达式构建二叉树,可以采用递归的方法: ```cpp void ExpressionBinaryTree::buildBTreeByPrefixE() { std::stack<BinaryTreeNode*> s; std::string prefixExpr = getPrefixExpression(); int length = prefixExpr.length(); for (int i = length - 1; i >= 0; --i) { // 反向遍历字符串 char c = prefixExpr[i]; BinaryTreeNode* node = new BinaryTreeNode(c); if (!isOperator(c)) { // 如果是操作数,则创建叶子节点 s.push(node); } else { // 如果是操作符,则弹出两个子节点作为左右孩子 node->left = s.top(); s.pop(); node->right = s.top(); s.pop(); s.push(node); } } root = s.top(); // 最终栈顶即为根节点 } ``` 此函数通过反向前缀表达式逐字符读取,并利用栈保存中间结果,最终形成完整的二叉树。 ##### 中缀表达式构建二叉树 对于中缀表达式(标准形式书写的表达式,如“3 + 4”),需要先将其转换成后缀表达式再构建二叉树。这是因为中缀表达式涉及复杂的括号匹配和运算符优先级问题。通常会借助 Shunting Yard 算法完成这一过程[^2]。 ##### 后缀表达式构建二叉树 后缀表达式也称为逆波兰表达式,它不依赖于括号即可明确表达式的含义。“3 4 +”就是一个简单的例子。类似于前缀表达式的做法,也可以基于堆栈技术快速建立相应的二叉树。 ```cpp BinaryTreeNode* buildFromPostfix(const std::string& postfix) { std::stack<BinaryTreeNode*> stack; for(char ch : postfix){ if(isdigit(ch)){ stack.push(new BinaryTreeNode(ch)); } else{ BinaryTreeNode* opNode = new BinaryTreeNode(ch); opNode->right = stack.top(); stack.pop(); opNode->left = stack.top(); stack.pop(); stack.push(opNode); } } return stack.empty()? nullptr : stack.top(); } ``` 这段代码展示了如何从给定的后缀表达式直接构造一棵二叉树[^1]。 #### 存储优化与错误处理 当实际应用这些理论时,还需要注意一些细节问题。比如验证输入表达式的合法性是非常重要的一步;另外,在内存管理方面也要有所考量,避免不必要的资源浪费。例如,如果某些部分重复出现多次的话,可能考虑共享相同的子树以减少冗余。 #### 总结 综上所述,无论是哪种类型的表达式都可以有效地映射到二叉树模型上来解决复杂度较高的算术逻辑运算需求。同时针对不同场景下的特殊要求做出相应调整也是十分必要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值