获取一个网址的html

2018-02-27 11:27:14来源:oschina作者:pkookp8人点击

分享
import socket
# 创建socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接:
s.connect(('www.bing.com', 80))
request = 'GET / HTTP/1.1 /r/n/
Host: cn.bing.com/r/n/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0/r/n/
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8/r/n/
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2/r/n/
Connection: close/r/n/
Upgrade-Insecure-Requests: 1/r/n/
Pragma: no-cache/r/n/
Cache-Control: no-cache/r/n/r/n'
s.send(bytes(request, encoding = "utf8"))
# 接收:
buffer = []
while True:
d = s.recv(1024)
if d:
buffer.append(d)
else:
break
data = b''.join(buffer)
s.close()
header, html = data.split(b'/r/n/r/n', 1)
print(header.decode())
with open('bing.html', 'wb') as f:
f.write(html)

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432004374523e495f640612f4b08975398796939ec3c000#0


教程如上,基本上和liaoxuefeng老师的代码一模一样了,不过教程要到后面几章才开始讲http协议


因此先写一点记录


http协议的请求格式



姑且把响应格式也放上,这里用不到



http get的流程是:客户端(这里是python,也可以是浏览器)发送一个请求,服务器返回一个响应


作为一个用了2年C语言的码畜,根本不了解怎么自己构造一个http请求,只知道一个ua(user-agent)和一个饼干(cookie)


但是火狐(别和我说库若木,我只爱火狐)是一个很棒的浏览器,F12打开控制台



然后刷新一下页面,进入网络选项卡,查看消息头,就可以看到你进入这个网址后,向服务器所发的所有消息了


选择文件为'/',点击“编辑和重发”,可以直接修改http请求,这里不需要怎么修改,直接拿过来即可


Host: www.bing.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Cookie: xx
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache

根据ua可以看出这是一个windows的火狐58.0访问bing所产生的一个http请求


cookie是可选的,删除就行了


Accept-Encoding是一个麻烦的东西,获取到本地后会编程gzip格式的信息,如果直接写入文件会看到乱码,需要解码,我还不是很懂怎么解码,姑且去掉


然后根据请求格式补全


请求方法是GET,加空格,加url(这里应该是去掉Host的url)‘/’,再加空格,再加协议版本(现在常见的有1.0,1.1,2.0)‘HTTP/1.1’。


加上上面的消息头,别忘了每行结尾加上CRLF ‘/r/n’,和多数编程语言一样一段话换行可以加'/',也可以闲得没事自己改成一行,不过这样代码会比较难看。特别需要注意的是,最后有两个/r/n


把补全后的请求字符串放到python里面,然后通过bytes函数转为byte格式发送出去

如果代码运行后没有立即返回,可以尝试着把Connection: keep-alive改为Connection: close


我的猜测是浏览器并不会单独的只请求首页,还会请求例如js脚本、图片等等,可能是因为服务器需要优化性能,收不到这些请求就不返回消息,于是python就会阻塞在recv函数中,最后超时退出

结合上篇下载bing图片的代码:https://my.oschina.net/u/3774535/blog/1621920


可以修改request.urlopen方法为上述发送http请求的方法,然后解析recv到信息,也是可以得到图片的。这样有个好处,发送http请求的方式可以伪装ua,因为request.urlopen的ua是Python-urllib/xxx,某些网站为了防止被python爬文章爬图片,会过滤python的ua


最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台