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. hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  2. 一步一步从原理跟我学邮件收取及发送 3.telnet命令行发一封信

    首先要感谢博客园管理员的及时回复,本系列的第二篇文章得以恢复到首页,这是对作者的莫大鼓励.说实在的本来我真的挺受打击的.好在管理员说只是排版上有些问题,要用代码块修饰下相关的信息.说来惭愧因为常年编码 ...

  3. linphone-android-客户端APP-工程解读

    LinphoneLauncherActivity 是APP的入口组件,在这个组件里,它会启动LinphoneService这个后台服务,然后不断地判断这个后台服务是否已经启动完毕,如果已经启动完毕后, ...

  4. Linux 将本地文件上传Linux服务器, 即ssh 命令上传本地文件

    http://blog.csdn.net/rodulf/article/details/71169996 利用ssh传输文件 在linux下一般用scp这个命令来通过ssh传输文件. 1.从服务器上下 ...

  5. 最简Java程序

    本文是笔者创建项目--一系列java示例程序的总结.项目位置在SimplestJavaDemos,欢迎访问. 以下为正文: ---   作为一个伪完美主义+拖延癌患者,每次要学习新技术的时候,总是要把 ...

  6. 一天浓缩学习webpack经过

    熟话说浓缩就是精华,哈哈,所以就这么简单粗暴的介绍下吧,写下的都是精华. 已经不是第一次听说webpack,但是我的起步有点晚,现在才看.开门见山~~ 1.什么是webpack? webpack是当下 ...

  7. Dubbo底层采用Socket进行通信详解

    由于Dubbo底层采用Socket进行通信,自己对通信理理论也不是很清楚,所以顺便把通信的知识也学习一下. n  通信理论 计算机与外界的信息交换称为通信.基本的通信方法有并行通信和串行通信两种. 1 ...

  8. 通过Azure 存储账号URL鉴别是标准磁盘还是高性能磁盘

    对于不知道虚拟机磁盘是标准磁盘还是高性能磁盘时,我们可以通过nslookup解析存储账号的URL,来判断存储账号的类型,从而得知虚拟磁盘的类型 1.标准存储账号的解析结果,字母"st&quo ...

  9. Linux网络设备驱动架构

    Linux网络设备驱动程序体系结构分为四层:网络协议接口层.网络设备接口层.提供实际功能的设备驱动层以及网络设备与媒介层. (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是AR ...

  10. 设置PATH和CLASSPATH

    每天玩java的,如果连这门语言背景一点都熟悉的话,说出去真的是挺丢人的一件事情. 首先,java具有最强大的2个特点:功能强大,简单易用.出去android不说,这门语言衍生出太多的开源框架了,这也 ...