【问题标题】:Web scraping Address for a postcode list in pythonpython中邮政编码列表的Web抓取地址
【发布时间】:2020-01-24 11:02:18
【问题描述】:

是否可以根据postcoede从地址定位器网站上抓取地址。 如果可以使用scrapy或任何其他python库,请帮助我。

我有一个 .csv 中的邮政编码列表,我正在尝试提取这些邮政编码的地址信息 并保存在 .csv 或 .txt 中

假设一个列表包含邮政编码

POSTCODE
HU9 5PX  
OX5 1HX  

我正在尝试以 .csv 格式获取输出

HU9 5PX  Aarhus Karlshamn,King George Dock,HULL
OX5 1HX  Abric Europe Ltd,Langford Locks,KIDLINGTON

我试图做这样的事情。

import logging
import os
import pandas as pd
import re
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor
from googlesearch import search
logging.getLogger('scrapy').propagate = False

def get_urls(tag, n, language):
    urls = [url for url in search(tag, stop=n, lang=language)][:n]
    return urls

address_list = re.findall(a-z)


class MailSpider(scrapy.Spider):
    
    name = 'address'
    
    def parse(self, response):
        
        links = LxmlLinkExtractor(allow=()).extract_links(response)
        links = [str(link.url) for link in links]
        links.append(str(response.url))
        
        for link in links:
            yield scrapy.Request(url=link, callback=self.parse_link) 
            
    def parse_link(self, response):
        
        for word in self.reject:
            if word in str(response.url):
                return
            
        html_text = str(response.text)
        mail_list = re.findall('a-z', html_text)

但是上面的代码没有给出正确的结果。 错误:NameError:未定义名称“a” 请帮忙

【问题讨论】:

  • 是的,应该可以。尽管您需要展示您的尝试并带着您遇到的更具体的问题来到这里。您还需要创建一个Minimal, Reproducible Example
  • 分享一些数据作为示例以及您期望的最终结果。使您的问题陈述可重现。
  • @CypherX:嗨,我已经添加了预期输出的数据,我们可以使用这个网站获取地址吗? “royalmail.com/find-a-postcode”。请帮忙
  • address_list = re.findall(a-z) 这是你得到 NameError 的地方,这需要是一个字符串所以...("a-z")
  • @JoshuaNixon:谢谢....但仍然出现像 findall() 这样的错误需要至少 2 个参数(给定 1 个)...请帮助

标签: python web-scraping beautifulsoup scrapy


【解决方案1】:

这是可能的。不过,您还有其他选择。您可以使用 geopy、mapquest has 和 API,或理想的邮政编码。以下是它可以返回的一些结果(注意:您需要自己的 api 密钥来进行 mapquest)

POSTCODE_list = ['HU9 5PX', 'OX5 1HX']

代码:geopy

import geopy
from geopy.geocoders import Nominatim

geopy.geocoders.options.default_user_agent = "locations-application"
geolocator=Nominatim(timeout=10) 

for postal_code in POSTCODE_list:
    location = geolocator.geocode('%s' %(postal_code))
    print (location)

输出:

Kingston upon Hull, HU9 5PX, UK
Kidlington, OX5 1HX, UK

代码:mapquest api

import requests

for postal_code in POSTCODE_list:    
    url = 'http://www.mapquestapi.com/geocoding/v1/address?key=<ENTER YOU API KEY HERE>&location=%s' %postal_code
    r = requests.get(url)
    results = r.json()['results']

    print (results[0]['locations'])

输出:

[{'street': '', 'adminArea6': '', 'adminArea6Type': 'Neighborhood', 'adminArea5': 'Kingston upon Hull', 'adminArea5Type': 'City', 'adminArea4': 'Kingston upon Hull, City of', 'adminArea4Type': 'County', 'adminArea3': '', 'adminArea3Type': 'State', 'adminArea1': 'GB', 'adminArea1Type': 'Country', 'postalCode': 'HU9 5PX', 'geocodeQualityCode': 'Z1XAA', 'geocodeQuality': 'ZIP', 'dragPoint': False, 'sideOfStreet': 'N', 'linkId': '287067758', 'unknownInput': '', 'type': 's', 'latLng': {'lat': 53.746092, 'lng': -0.270408}, 'displayLatLng': {'lat': 53.746092, 'lng': -0.270408}, 'mapUrl': 'http://www.mapquestapi.com/staticmap/v5/map?key=ZGPYZNMeDbhK2NVXjTQ944ejAm2F1kqG&type=map&size=225,160&locations=53.746092,-0.270408|marker-sm-50318A-1&scalebar=true&zoom=15&rand=-982249466'}]
[{'street': '', 'adminArea6': '', 'adminArea6Type': 'Neighborhood', 'adminArea5': 'Kidlington', 'adminArea5Type': 'City', 'adminArea4': 'Oxfordshire', 'adminArea4Type': 'County', 'adminArea3': '', 'adminArea3Type': 'State', 'adminArea1': 'GB', 'adminArea1Type': 'Country', 'postalCode': 'OX5 1HX', 'geocodeQualityCode': 'Z1XAA', 'geocodeQuality': 'ZIP', 'dragPoint': False, 'sideOfStreet': 'N', 'linkId': '287512940', 'unknownInput': '', 'type': 's', 'latLng': {'lat': 51.830272, 'lng': -1.305073}, 'displayLatLng': {'lat': 51.830272, 'lng': -1.305073}, 'mapUrl': 'http://www.mapquestapi.com/staticmap/v5/map?key=ZGPYZNMeDbhK2NVXjTQ944ejAm2F1kqG&type=map&size=225,160&locations=51.830272,-1.305073|marker-sm-50318A-1&scalebar=true&zoom=15&rand=-1049337783'}]

代码:理想邮政编码

import requests
import pandas as pd

postal_code_df = pd.read_csv('file.csv')    


results = pd.DataFrame()    
for postal_code in postal_code_df['postal_code_column_name']:  # <---- USE THE HEADER NAME FOR THAT COLUMN IN YOUR FILE
    postal_code = ''.join(postal_code.split())
    url = 'https://api.ideal-postcodes.co.uk/v1/postcodes/%s?api_key=iddqd' %(postal_code)
    data = requests.get(url).json()

    data = data['result'][0]

    print ('%s %s, %s, %s' %(postal_code, data['organisation_name'], data['line_2'], data['post_town']))
    temp_df = pd.DataFrame([[postal_code, data['organisation_name'], data['line_2'], data['post_town']]],
                            columns=['postal_code','organisation','street','town'])

    results = results.append(temp_df, sort=True).reset_index(drop=True)

results.to_csv('file.csv', index=False)

输出:

HU95PX Aarhus Karlshamn, King George Dock, HULL
OX51HX Essentra Components Ltd, Langford Locks, KIDLINGTON

【讨论】:

  • 非常感谢.... 最后一个问题是可以添加包含代码而不是列表的文件路径。因为我有 300 个邮政编码
  • 嗨。我在这里需要你的帮助,当我尝试在以“D:/sourcefile/postalcode.csv”给出的路径中保存的 .csv 文件上运行代码时,它的抛出错误为 KeyError:'postal_code_column_name'。如果文件包含无效的邮政编码,会发生错误。非常感谢
  • 是的。您需要将该字符串更改为该列上的标题。我没有你的文件,所以我不知道你叫什么。
  • requests.exceptions.SSLError: HTTPSConnectionPool(host='api.ideal-postcodes.co.uk', port=443): 最大重试次数超出了 url: /v1/postcodes/CN-511450? api_key=iddqd (由 SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))......试图找出原因。
  • 啊啊啊。好的。是的,这可能会导致错误。我明天要看看,因为我刚下班。但我们可以解决这个问题(或至少解决它)。可以寄给我或张贴您的邮政编码列表吗?所以我可以看到那里还有哪些其他格式?我假设它们都是“AAA AAA”格式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
相关资源
最近更新 更多