鱼C论坛

 找回密码
 立即注册
查看: 1023|回复: 7

[已解决]小白有一些问题,麻烦各位鱼油有空的话帮忙进来看看

[复制链接]
发表于 2019-6-29 14:27:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
PS:我的疑问在解决方案二那里,前面只是顺带给遇到和我一样情况的小白一些解决方案
原代码:
import  urllib.request
import urllib.parse
import string
def get_method_params():
    url = "https://www.baidu.com/s?tn=88093251_17_hao_pg&ie=utf-8&sc=UWY3rj04n1cdnNtkPdqCmyqxTAThIjYkPHmkPWbvnjn3PHb3FhnqpA7EnHc1Fh7W5HndPWfsnjbsPj0&ssl_sample=s_88&srcqid=3243340699557307542&H123Tmp=nunew7&word="
    #拼接字符串(汉字)
    #python可以接受的数据
    #
    name ="美女"
    final_url = url + name
    print(final_url)
    #代码发送了请求
    #网址里面包含了汉字,ascii是没有汉字的,需要url转译
    #将包含汉字的网址进行转译
    encode_new_url = urllib.parse.quote(final_url,safe = string.printable)
    print(encode_new_url)
    #使用代码发送网络请求
    response = urllib.request.urlopen(encode_new_url)
    print(response)
    data = response.read().decode()
    print(data)
    #保存到本地
    with open("02-encode.html","w",encoding = "utf-8") as f:
        f.write(data)
    #UnicodeEncodeError: 'ascii' codec can't encode characters in position 184-185: ordinal not in range(128)
    #原因:python是解释性语言,解析器只支持  ascii只支持 0-127,即不支持中文
get_method_params()
这个程序运行后生成html文件会不断地跳转,按理说本应该跳转到百度知道一个美女的搜索页面,于是我昨天在鱼C论坛发了求助帖,得到了鱼油们的热情帮助,问题也得到了解决,但是现在又出现了一些困惑,希望路过的大神帮忙看看。
问题出现原因:百度的反爬虫机制user-agent造成的
解决方案一(本答案来源于鱼C论坛@newu):加上header
import  urllib.request
import urllib.parse
import string
def get_method_params():
    url = "https://www.baidu.com/s?ie=UTF-8&wd="
    headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.204 Safari/537.36',
    }
    #拼接字符串(汉字)
    #python可以接受的数据
    #
    name ="美女"
    final_url = url + name
    print(final_url)
    #代码发送了请求
    #网址里面包含了汉字,ascii是没有汉字的,需要url转译
    #将包含汉字的网址进行转译
    encode_new_url = urllib.parse.quote(final_url,safe = string.printable)
    print(encode_new_url)
    #使用代码发送网络请求
    req = urllib.request.Request(encode_new_url, headers=headers) # 加个头就好了
    response = urllib.request.urlopen(req)
    print(response)
    data = response.read().decode()
    print(data)
    #保存到本地
    with open("02-encode.html","w",encoding = "utf-8") as f:
        f.write(data)
    #UnicodeEncodeError: 'ascii' codec can't encode characters in position 184-185: ordinal not in range(128)
    #原因:python是解释性语言,解析器只支持  ascii只支持 0-127,即不支持中文
get_method_params()
解决方案二(自己无意间尝试出来的,但是不明白具体原因,希望明白的鱼油们解惑):
将get_method_params()方法下下第一行的
url = "https://www.baidu.com/s?tn=88093251_17_hao_pg&ie=utf-8&sc=UWY3rj04n1cdnNtkPdqCmyqxTAThIjYkPHmkPWbvnjn3PHb3FhnqpA7EnHc1Fh7W5HndPWfsnjbsPj0&ssl_sample=s_88&srcqid=3243340699557307542&H123Tmp=nunew7&word="
改为
url="https://www.baidu.com/s?wd="
生成的HTML文件依然可以保证正常打开,但是这样改后,在程序执行到
response = urllib.request.urlopen(encode_new_url)
的时候,会非常地慢,但是依然可以正常生成HTML文件,并且可以正常打开,求助大神,第二种解决方案的原理是是什么?又是什么原因造成了调用urlopen()方法打开网址的时候速度十分缓慢?
最佳答案
2019-6-29 14:56:39
MadJoker 发表于 2019-6-29 14:48
就在刚才你问我确认方案2是否可行的时候,我再次试了一次,真的能行,但是反应很慢就是

了解了,我尝试了下使用
url="http://www.baidu.com/s?wd="
就是不要用baidu的SSL加密协议来请求他就可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-29 14:36:10 | 显示全部楼层
确定方案2可以吗?我怎么没尝试成功,是不是还是第一次生成成功的html文件啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-29 14:47:40 | 显示全部楼层
newu 发表于 2019-6-29 14:36
确定方案2可以吗?我怎么没尝试成功,是不是还是第一次生成成功的html文件啊

你刚才说了之后,我重新建了一个工程,把以前写的文件都删除了,第一次先用长的url,结果还是不断地跳转,然后我用了短的url,和上述的情况一直,响应巨慢无比,但是却可以正常跳转了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-29 14:48:42 | 显示全部楼层
newu 发表于 2019-6-29 14:36
确定方案2可以吗?我怎么没尝试成功,是不是还是第一次生成成功的html文件啊

就在刚才你问我确认方案2是否可行的时候,我再次试了一次,真的能行,但是反应很慢就是
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-29 14:54:35 | 显示全部楼层
MadJoker 发表于 2019-6-29 14:48
就在刚才你问我确认方案2是否可行的时候,我再次试了一次,真的能行,但是反应很慢就是

是这样的代码吗?如果是的话我的怎么不行欸
  1. import urllib.request
  2. import urllib.parse
  3. import string


  4. url = "https://www.baidu.com/s?wd="
  5. name ="测试"
  6. final_url = url + name
  7. encode_new_url = urllib.parse.quote(final_url,safe = string.printable)
  8. response = urllib.request.urlopen(encode_new_url)
  9. data = response.read().decode()
  10. print(data)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-29 14:56:39 | 显示全部楼层    本楼为最佳答案   
MadJoker 发表于 2019-6-29 14:48
就在刚才你问我确认方案2是否可行的时候,我再次试了一次,真的能行,但是反应很慢就是

了解了,我尝试了下使用
url="http://www.baidu.com/s?wd="
就是不要用baidu的SSL加密协议来请求他就可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-29 15:09:49 | 显示全部楼层
MadJoker 发表于 2019-6-29 14:48
就在刚才你问我确认方案2是否可行的时候,我再次试了一次,真的能行,但是反应很慢就是

反应慢可能与网络有关系,你试试用requests模块速度如何,我这边requests模块速度好像被urllib快一些
  1. import requests

  2. url = "http://www.baidu.com/s?wd="
  3. name ="测试"
  4. response = requests.get(url + name)
  5. print(response.text)
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-29 15:54:11 | 显示全部楼层
个人觉得requests好用 又简单
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-19 19:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表