Foundations of Python Network Programing,Third Edition 《python网络编程》,本书中的代码可在Github上搜索fopnp下载

本书的第一章中使用到了google地图的api来获取一个地址的经度和纬度,因为众所周知的原因会出现无法访问,我们需要使用代理访问

因此书上的代码需要根据实际情况来修改,我的电脑的代理地址为127.0.0.1:1080,下面放我的代码吧,可根据自己电脑的代理设置进行修改。

运行环境:Windows 10,Anaconda3,python3.6.3,Pycharm Edu 2017.3

调用库:

#search1.py

from pygeocoder import Geocoder

if __name__ == '__main__':
a = Geocoder()
a.proxy = "127.0.0.1:1080"
address = '207 N. Definace St,Archbold,OH'
print(a.geocode(address)[0].coordinates)

这里使用的是Geocoder中的proxy参数设置代理(需要先使用pip安装pygeocoder),因此必须先实例化,不能像书中一样直接print

应用层:

#search2.py

import requests

proxies = {"http": "http://127.0.0.1:1080", "https": "http://127.0.0.1:1080", }

def geocode(address):
parameters = {'address': address, 'sensor': 'falise'}
base = 'http://maps.googleapis.com/maps/api/geocode/json'
response = requests.get(base, params=parameters, proxies=proxies)
answer = response.json()
print(answer['results'][0]['geometry']['location']) if __name__ == '__main__':
geocode('207 N. Defiance St,Archbold, OH')

这里使用了requests中的proxies参数设置代理

使用HTTP协议:

# search3.py

import http.client
import json
from urllib.parse import quote_plus base = '/maps/api/geocode/json' def geocode(address):
path = '{}?address={}&sensor=false'.format(base, quote_plus(address))
connection = http.client.HTTPSConnection('127.0.0.1', 1080)
connection.set_tunnel('map.google.com')
connection.request('GET', path)
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode('utf-8'))
print(reply['results'][0]['geometry']['location']) if __name__ == '__main__':
geocode('207 N. Defiance St,Archbold, OH')

这里会提示

Traceback (most recent call last):
File "E:/Learn Python/Python网络编程/search3.py", line 21, in <module>
geocode('207 N. Defiance St,Archbold, OH')
File "E:/Learn Python/Python网络编程/search3.py", line 16, in geocode
reply = json.loads(rawreply.decode('utf-8'))
File "D:\Anaconda3\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "D:\Anaconda3\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "D:\Anaconda3\lib\json\decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Process finished with exit code 1

很明显报了一个json.decoder.JSONDecodeError的错误 说明没有能够正确访问,json decode失败

print(rawreply)发现rawreply返回的是这样的html文件

b'<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">\n
<TITLE>301 Moved</TITLE></HEAD><BODY>\n<H1>301 Moved</H1>\n
The document has moved\n
<A HREF="https://maps.google.com/maps/api/geocode/json?address=207+N.+Defiance+St%2CArchbold%2C+OH&sensor=false">here</A>.\r\n
</BODY>
</HTML>
\r\n'

返回了一个301错误,说明需要重定向这里我们使用的是HTTPS协议因此不会像浏览器一样直接重定向,感觉应该是google反爬虫的一种行为

因此我们使用正则表达式提取字符串(方法来自https://www.cnblogs.com/rj81/p/5933838.html),更改后代码如下

# search3.py

import http.client
import json
from urllib.parse import quote_plus
import re base = '/maps/api/geocode/json' def geocode(address):
path = '{}?address={}&sensor=false'.format(base, quote_plus(address))
connection = http.client.HTTPSConnection('127.0.0.1', 1080)
connection.set_tunnel('map.google.com')
connection.request('GET', path)
rawreply = connection.getresponse().read().decode()
newweb = re.findall(r"HREF=\"(.+?)\"", string=rawreply)
# print(newweb)
connection.request('GET', newweb[0])
rawreply = connection.getresponse().read()
# print(path)
# print(rawreply)
reply = json.loads(rawreply.decode('utf-8'))
print(reply['results'][0]['geometry']['location']) if __name__ == '__main__':
geocode('207 N. Defiance St, Archbold, OH')

即可正确输出结果

{'lat': 41.5219645, 'lng': -84.3066496}

Process finished with exit code 0

这里需要注意的是 我一开始以为newweb是一个str,直接使用了connection.request('GET', newweb)

结果发现AttributeError: 'list' object has no attribute 'startswith'的错误,更改之后即可正常输出

直接使用Socket与谷歌地图通信:

设置代理的方法(转自http://www.jb51.net/article/50510.htm)

urllib2:

proxy_handler = urllib2.ProxyHandler({'http' : 'http://地址:端口'})
opener = urllib2.build_opener(proxy_handler, urllib2.HTTPHandler)
urllib2.install_opener(opener)

socket:

import socks, socket
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "地址", 端口)
socket.socket = socks.socksocket

代码如下:

#search4.py
#!/usr/bin/env python3 import socket
import socks
from urllib.parse import quote_plus request_text = """\
GET /maps/api/geocode/json?address={}&sensor=false HTTP/1.1\r\n\
Host: maps.google.com:80\r\n\
User-Agent: search4.py (Foundations of Python Network Programming)\r\n\
Connection: close\r\n\
\r\n\
""" def geocode(address):
socks.set_default_proxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 1080)
socket.socket = socks.socksocket
sock = socket.socket()
sock.connect(('maps.google.com', 80))
request = request_text.format(quote_plus(address))
sock.sendall(request.encode('ascii'))
raw_reply = b''
while True:
more = sock.recv(4096)
if not more:
break
raw_reply += more
print(raw_reply.decode('utf-8')) if __name__ == '__main__':
geocode('207 N. Defiance St, Archbold, OH')

运行输出:

HTTP/1.1  OK
Content-Type: application/json; charset=UTF-
Date: Fri, Jan :: GMT
Expires: Sat, Jan :: GMT
Cache-Control: public, max-age=
Access-Control-Allow-Origin: *
Server: mafe
X-XSS-Protection: ; mode=block
X-Frame-Options: SAMEORIGIN
Accept-Ranges: none
Vary: Accept-Language,Accept-Encoding
Connection: close {
"results" : [
{
"address_components" : [
{
"long_name" : "",
"short_name" : "",
"types" : [ "street_number" ]
},
{
"long_name" : "North Defiance Street",
"short_name" : "N Defiance St",
"types" : [ "route" ]
},
{
"long_name" : "Archbold",
"short_name" : "Archbold",
"types" : [ "locality", "political" ]
},
{
"long_name" : "German Township",
"short_name" : "German Township",
"types" : [ "administrative_area_level_3", "political" ]
},
{
"long_name" : "Fulton County",
"short_name" : "Fulton County",
"types" : [ "administrative_area_level_2", "political" ]
},
{
"long_name" : "Ohio",
"short_name" : "OH",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "United States",
"short_name" : "US",
"types" : [ "country", "political" ]
},
{
"long_name" : "",
"short_name" : "",
"types" : [ "postal_code" ]
},
{
"long_name" : "",
"short_name" : "",
"types" : [ "postal_code_suffix" ]
}
],
"formatted_address" : "207 N Defiance St, Archbold, OH 43502, USA",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : 41.521994,
"lng" : -84.30646179999999
},
"southwest" : {
"lat" : 41.521935,
"lng" : -84.30683739999999
}
},
"location" : {
"lat" : 41.5219645,
"lng" : -84.3066496
},
"location_type" : "ROOFTOP",
"viewport" : {
"northeast" : {
"lat" : 41.5233134802915,
"lng" : -84.30530061970849
},
"southwest" : {
"lat" : 41.5206155197085,
"lng" : -84.3079985802915
}
}
},
"place_id" : "ChIJk4BHnIy0PYgRXbKj5GjFe_U",
"types" : [ "premise" ]
}
],
"status" : "OK"
} Process finished with exit code 0

《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档的更多相关文章

  1. python网络编程学习笔记(三):socket网络服务器(转载)

    1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对 ...

  2. python网络编程学习笔记(10):webpy框架

    转载请注明:@小五义http://www.cnblogs.com/xiaowuyi django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站. ...

  3. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  4. 转 网络编程学习笔记一:Socket编程

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  5. Java网络编程学习笔记

    Java网络编程,我们先来看下面这一张图: 由图可得:想要进行网络编程,首先是服务器端通过ServerSocket对某一个端口进行监听.通过accept来判断是否有客户端与其相连.若成功连上,则通过r ...

  6. python网络编程学习《一》

    最近,刚实习完,很喜欢实验楼,但是自己的方向仍然不能确定,自己觉得可选择的空间很大,尽管已经是大四的人了,想到别人都在忙着买职业装,买高跟鞋面试,学习化妆什么的,看看自己,反而开始慢慢关注运动,食疗以 ...

  7. python网络爬虫学习笔记(一)Request库

    一.Requests库的基本说明 引入Rquests库的代码如下 import requests 库中支持REQUEST, GET, HEAD, POST, PUT, PATCH, DELETE共7个 ...

  8. Java Socket网络编程学习笔记(一)

    0.前言 其实大概半年前就已经看过网络编程Socket的知识了(传统IO),但是因为长时间的不使用导致忘的一干二净,最近正好准备校招,又重新看了网络编程这一章, 是传统IO(BIO)相关的内容,故在此 ...

  9. python网络爬虫学习笔记(二)BeautifulSoup库

    Beautiful Soup库也称为beautiful4库.bs4库,它可用于解析HTML/XML,并将所有文件.字符串转换为'utf-8'编码.HTML/XML文档是与“标签树一一对应的.具体地说, ...

随机推荐

  1. 51Nod 1182 完美字符串(字符串处理 贪心 Facebook Hacker Cup选拔)

    1182 完美字符串             题目来源:                         Facebook Hacker Cup选拔         基准时间限制:1 秒 空间限制:1 ...

  2. HDU2825 Wireless Password

    Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...

  3. 我的第三个网页制作:b、i、s、u、sub、sup标签的使用

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. asp.net网站管理工具 遇到错误。请返回上一页并重试。

    原因:项目的路径里有“#”号.

  5. cnzz友盟怎么安装网站统计代码监控网站流量

    做网站的都知道cnzz统计,它是用来统计网站流量的,可以分析网站数据,进行更好的对网站优化,下面我教大家怎么添加统计代码 工具/原料 cnzz 方法/步骤 打开百度搜索"cnzz友盟&quo ...

  6. html dl dt dd标签元素语法结构与使用

    dl dt dd认识及dl dt dd使用方法 标签用于定义列表类型标签. dl dt dd目录 dl dt dd介绍 结构语法 dl dt dd案例 dl dt dd总结 一.dl dt dd认识 ...

  7. LNMP 与 LAMP 架构的区别及配置解决方案

    2014-12-31 10:33| 发布者: digitser| 查看: 5618| 评论: 0|原作者: liangsheng 摘要: LNMP 与 LAMP 架构的区别及配置解决方案 LNMP 的 ...

  8. CSAPP 第二章随笔

    类型转换问题 (1)int -> short 二进制位高位截断,低位保持不变 (2)同类型 unsign -> sign 记住二进制位是不变的 (3)P101页提到的编译器乘法优化问题,一 ...

  9. XHR

    xhr注入 XHR 注入技术是通过XMLHttpRequest来获取javascript的.但与eval不同的是,该机制是通过创建一个script的DOM元素,然后把XMLHttpRequest的响应 ...

  10. 利用 HTML5 WebGL 构建的 3D 拓扑图

    现在,3D 模型已经用于各种不同的领域.在医疗行业使用它们制作器官的精确模型:电影行业将它们用于活动的人物.物体以及现实电影:视频游戏产业将它们作为计算机与视频游戏中的资源:在科学领域将它们作为化合物 ...