Weather in 3 cities
Open the same weather page through residential proxies in New York, London and Tokyo, with the browser in "realistic" mode (its clock and language follow the proxy), and compare the local weather and time.
When to use it: You need a browser that looks local in a given city: its address, clock and language.
| Uses | sessions with proxy: {type: "residential", country, city} and browser: {mode: "realistic"} |
|---|---|
| Needs | a plan with residential proxies and the realistic browser (proxy traffic counts against the allowance) |
| Site | wttr.in (weather for the place a request comes from) |
| Output | output/result.json: one row per city |
| Languages | Node and Python |
The code
The example as it is in its folder. Both versions do the same job and write the same output/, so one result check covers both.
/** * Weather in 3 cities: open the same weather page through residential proxies in three cities, with the browser in * "realistic" mode (its clock and language follow the proxy), and compare the local weather and time. * * npx tsx node/index.ts (BOXLINE_API_KEY; a plan with residential proxies and the realistic browser) * * wttr.in picks the weather for the place the request comes from. Proxy traffic counts against the plan's allowance. * Writes output/result.json. */import { mkdirSync, writeFileSync } from "node:fs";import { join } from "node:path";import { Boxline } from "@boxline/sdk";const out = process.env.OUTPUT_DIR ?? "output";const CITIES = [ { name: "New York", country: "US", city: "new_york" }, { name: "London", country: "GB", city: "london" }, { name: "Tokyo", country: "JP", city: "tokyo" },];const bx = new Boxline();const rows = [];for (const c of CITIES) { const session = await bx.sessions.create({ timeout: 300, proxy: { type: "residential", country: c.country, city: c.city }, browser: { mode: "realistic" }, userMetadata: { example: "weather-in-3-cities" }, }); console.log(`Session: ${session.id} (${c.name})`); try { await session.goto("https://wttr.in/?format=j1"); const { content } = await session.content("text"); // Chrome shows JSON as text (with its own "Pretty-print" control around it): parse from the first { to the last }. const w = JSON.parse(content.slice(content.indexOf("{"), content.lastIndexOf("}") + 1)) as { current_condition: any[]; nearest_area: any[] }; const clock = await session.evaluate<{ time: string; timeZone: string; language: string }>( "({ time: new Date().toString(), timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, language: navigator.language })", ); const now = w.current_condition[0]; const area = w.nearest_area[0]; rows.push({ city: c.name, area: `${area.areaName[0].value}, ${area.country[0].value}`, tempC: Number(now.temp_C), weather: now.weatherDesc[0].value, ...clock, }); console.log(`${c.name}: ${area.areaName[0].value}, ${now.temp_C} °C, ${now.weatherDesc[0].value}; the browser's clock: ${clock.time} (${clock.timeZone}, ${clock.language})`); } finally { await session.stop(); }}mkdirSync(out, { recursive: true });writeFileSync(join(out, "result.json"), JSON.stringify({ rows }, null, 2));"""Weather in 3 cities: open the same weather page through residential proxies in three cities, with the browser in"realistic" mode (its clock and language follow the proxy), and compare the local weather and time. python python/main.py (BOXLINE_API_KEY; a plan with residential proxies and the realistic browser)wttr.in picks the weather for the place the request comes from. Proxy traffic counts against the plan's allowance.Writes output/result.json."""import jsonimport osfrom pathlib import Pathfrom boxline import Boxlineout = Path(os.environ.get("OUTPUT_DIR", "output"))CITIES = [ {"name": "New York", "country": "US", "city": "new_york"}, {"name": "London", "country": "GB", "city": "london"}, {"name": "Tokyo", "country": "JP", "city": "tokyo"},]bx = Boxline()rows = []for c in CITIES: with bx.sessions.create( timeout=300, proxy={"type": "residential", "country": c["country"], "city": c["city"]}, browser_options={"mode": "realistic"}, user_metadata={"example": "weather-in-3-cities"}, ) as session: print(f"Session: {session.id} ({c['name']})", flush=True) session.goto("https://wttr.in/?format=j1") # Chrome shows JSON as text (with its own "Pretty-print" control around it): parse from the first { to the last }. text = session.content("text")["content"] w = json.loads(text[text.index("{"): text.rindex("}") + 1]) clock = session.evaluate("({ time: new Date().toString(), timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, language: navigator.language })") now, area = w["current_condition"][0], w["nearest_area"][0] rows.append({ "city": c["name"], "area": f"{area['areaName'][0]['value']}, {area['country'][0]['value']}", "tempC": float(now["temp_C"]), "weather": now["weatherDesc"][0]["value"], **clock, }) print(f"{c['name']}: {area['areaName'][0]['value']}, {now['temp_C']} °C, {now['weatherDesc'][0]['value']}; " f"the browser's clock: {clock['time']} ({clock['timeZone']}, {clock['language']})")out.mkdir(parents=True, exist_ok=True)(out / "result.json").write_text(json.dumps({"rows": rows}, indent=2, ensure_ascii=False))Run it
Get the examples with git clone https://github.com/Boxline-dev/examples.git and open this one: cd examples/weather-in-3-cities. Put your API key in BOXLINE_API_KEY (and BOXLINE_API_URL for another API), then run either version from the example’s folder. Both write to output/ and stop their sessions when they finish.
# Node 18 or newer, in the example's folderexport BOXLINE_API_KEY=… # your API keynpm install @boxline/sdk tsxnpx tsx node/index.ts# Python 3.9 or newer, in the example's folderexport BOXLINE_API_KEY=… # your API keypip install boxline-sdkpython python/main.pyThen check the result, from the same folder: npx tsx check.ts output. It exits with 0 only when the result is right.
What its check proves
check.ts reads what the example wrote and passes only when the result is right, not merely when the example ran.
Each browser's time zone and wttr.in's place match the proxy's city.
Source
github.com/Boxline-dev/examples/weather-in-3-cities on GitHub, with its README.md, check.ts and .env.example. The examples are open source. See all examples.
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.