Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Craigslist搜索-跨区域脚本

Craigslist搜索-跨区域脚本
EN

Code Review用户
提问于 2013-06-26 22:35:18
回答 1查看 513关注 0票数 5

我是一个JavaScript开发人员。我很肯定这一点在下面的代码中会立即显现出来,如果没有其他原因,那就是我喜欢的链接的级别/深度。但是,我正在学习Ruby,所以我也很想编写漂亮的Ruby代码。我的第一个简单项目是一个Craigslist搜索跨区域脚本。

完整的代码是论GitHub,但是分解为下面的问题片段。

代码语言:javascript
运行
AI代码解释
复制
def get_us_regions()
  # Accumulator for building up the returned object.
  results = {}

  # Important URLs
  sitelist = URI('http://www.craigslist.org/about/sites')
  geospatial = URI('http://www.craigslist.org/about/areas.json')

  # Get a collection of nodes for the US regions out of craigslist's site list.
  usregions =  Nokogiri::HTML(Net::HTTP.get(sitelist)).search("a[name=US]").first().parent().next_element().search('a')

  # Parse out the information to build a usable representation.
  usregions.each { |usregion|
    hostname = usregion.attr('href').gsub('http://','').gsub('.craigslist.org','')
    results[hostname] = { name: usregion.content, state: usregion.parent().parent().previous_element().content }
  }

  # Merge that information with craigslist's geographic information.
  areas = JSON.parse(Net::HTTP.get(geospatial))
  areas.each { |area|
    if results[area["hostname"]]
      results[area["hostname"]][:stateabbrev] = area["region"]
      results[area["hostname"]][:latitude] = area["lat"]
      results[area["hostname"]][:longitude] = area["lon"]
    end
  }

  # This is a complete list of the US regions, keyed off of their hostname.
  return results
end

引导

  • 我应该如何获得我需要开始的程序信息?
  • 如果我是在一个长期运行的应用程序的引导程序上这样做,并且想要刷新,比如说,每月刷新,那么这种情况会改变吗?
  • 我是不是应该把它放到一个真正抽象的类中呢?

这不是JS

  • 如何将调用链接到类方法?
  • 为什么要使用字符串键而不是奇怪的命名键呢?

对象-离子

  • 我是否应该为每个区域创建一个对象,并将我从文档中解析出来的部分输入构造函数?
  • 如果我这样做了,该构造函数应该只接受一个DOM节点并聪明地计算出我传递给它的内容吗?
  • 对于重新打开一个对象,因为我必须跨两个来源进行整理,什么是“正确”的方法?
代码语言:javascript
运行
AI代码解释
复制
# Perform a search in a particular region.
def search_region(regionhostname, query)
  # In case there are multiple pages of results from a search
  pages = []
  pagecount = false

  # An accumulator for storing what we need to return.
  result = []

  # Make requests for every page.
  while (pages.length != pagecount)
    # End up with a start of "0" on the first time, 100 is craigslist's page length.
    page = pages.length * 100    

    # Here is the URL we'll be making the request of.
    url = URI("http://#{regionhostname}.craigslist.org/search/cto?query=#{query}&srchType=T&s=#{page}")

    # Get the response and parse it.
    pages << Nokogiri::HTML(Net::HTTP.get(url))

    # If this is the first time through
    if (pagecount == false)

      #check to make sure there are results.
      if pages.last().search('.resulttotal').length() != 0
        # There are results, and we need to see if additional requests are necessary.
        pagecount = (pages.last().search('.resulttotal').first().content().gsub(/[^0-9]/,'').to_i / 100.0).ceil
      else
        # There are no results, we're done here.
        return []
      end
    end
  end

  # Go through each of the pages of results and process the listings
  pages.each { |page|
    # Go through all of the listings on each page
    page.search('.row').each { |listing|
      # Skip listings from other regions in case there are any ("FEW LOCAL RESULTS FOUND").
      if listing.search('a[href^=http]').length() != 0
        next
      end

      # Parse information out of the listing.
      car = {}
      car["id"] = listing["data-pid"]
      car["date"] = listing.search(".date").length() == 1 ? Date.parse(listing.search(".date").first().content) : nil
      # When Craigslist wraps at the end of the year it doesn't add a year field.
      # Fortunately Craigslist has an approximately one month time limit that makes it easy to know which year is being referred to.
      # Overshooting by incrementing the month to make sure that timezone differences between this and CL servers don't result in weirdness
      if car["date"].month > Date.today.month + 1
        car["date"] = car["date"].prev_year
      end
      car["link"] = "http://#{regionhostname}.craigslist.org/cto/#{car['id']}.html"
      car["description"] = listing.search(".pl > a").length() == 1 ? listing.search(".pl > a").first().content : nil
      car["price"] = listing.search("span.price").length() == 1 ? listing.search("span.price").first().content : nil
      car["location"] = listing.search(".l2 small").length() == 1 ? listing.search(".l2 small").first().content.gsub(/[\(\)]/,'').strip : nil
      car["longitude"] = listing["data-longitude"]
      car["latitude"] = listing["data-latitude"]

      # Pull car model year from description
      # Can be wrong, but likely to be accurate.
      if /(?:\b19[0-9]{2}\b|\b20[0-9]{2}\b|\b[0-9]{2}\b)/.match(car["description"]) { |result|

        # Two digit year
        if result[0].length == 2
          # Not an arbitrary wrapping point like it is in MySQL, etc.
          # Cars have known manufacture dates and can't be too far in the future.
          if result[0].to_i <= Date.today.strftime("%y").to_i + 1
            car["year"] = "20#{result[0]}"
          else
            car["year"] = "19#{result[0]}"
          end
        # Four digit year is easy.
        elsif result[0].length == 4
          car["year"] = result[0]
        end
      }
      else
        car["year"] = nil
      end

      # Store the region lookup key.
      car["regionhostname"] = regionhostname

      result << car
    }
  }

  return result
end

Car与Listing

  • 现在我有两个可能的“竞争”对象,如果我要把它扔到一个类中。清单描述的是一辆汽车,但我关心的是从两者中获取信息。我应该把它们都储存起来并连接起来吗?一辆“有一辆”的车?

结果页

  • 每个页面应该是一个对象吗?我首先要了解的是,我需要请求多少页。
  • 我该如何防止它连续运行呢?我是否应该通过返回函数将这些函数泡沫化?这真的有可能在Ruby中做到干净吗?

如果代码看起来像这样.

  • 我正在检查的if语句是否存在(并两次调用该方法)是很糟糕的。但是,如果我试图访问不存在的东西,它会抛出丑陋的错误。
  • 三元是我发现的最好的,还有其他的窍门吗?

Misc.

  • “下一个”很受欢迎吗?
  • 有从匹配对象中提取信息的成语吗?
  • 那建立关系呢?我这样做对吗?
代码语言:javascript
运行
AI代码解释
复制
def search(query)
  results = []

  # Get a copy of the regions we're going to search.
  regions = get_us_regions()

  # Divide the requests to each region across the "right" number of threads.
  iterations = 5
  count = (regions.length/iterations.to_f).ceil

  # Spin up the threads!
  (0..(iterations-1)).each { |iteration|
    threads = []

    # Protect against source exhaustion
    if iteration * count > regions.length()
      next
    end

    # Split the requests by region.
    regions.keys.slice(iteration*count,count).each { |regionhostname|
      threads << Thread.new(regionhostname) { |activeregionhostname|
        # New block for proper scoping of regionhostname
        results << search_region(activeregionhostname, query)
      }
    }

    # Wait until all threads are complete before kicking off the next set.
    threads.each { |thread| thread.join }
  }

  # From search_region we return an array, which means we need to flatten(1) to pull everything up to the top level.
  results = results.flatten(1)

  # Sort the search results by date, descending.
  results.sort! { |a,b|
    if a["date"] == b["date"]
      b["id"].to_i <=> a["id"].to_i
    else
      b["date"] <=> a["date"]
    end
  }

  return results
end

puts search("TDI").to_json

public static void main

  • 穿线!异步代码对我来说是有意义的,但是如果我一次创建太多的代码,我的(Ruby)线程就会崩溃。是否有为一组工作线程排队活动的成语?
  • 为了陈述?还是(0..5).each {x=0 }?
  • 对象集合的全局?只在“主”里?
  • 我是不是做错了命名约定?
  • 还有什么我应该问的吗?

结论

代码可以工作,您可以使用它从每个区域获得结果,以便在Craigslist上搜索汽车。这对于稀有/难找的车辆来说是件好事。我希望线程更好,并在不同的线程上包含来自分页的多个请求,但是我需要一些池来处理这个问题。最后,我考虑将Rack集成到这个简单的车辆搜索API中。或者,它会变得更聪明,并将结果存储在数据库中,以跟踪一段时间的价格,创造出更多受过良好教育的卖家和消费者,或者标记出好的交易。

EN

回答 1

Code Review用户

回答已采纳

发布于 2013-06-27 12:55:48

很长很长的问题我会拿走你的第一个片段,让其他人来处理剩下的。首先,关于您的代码的一些评论:

  • def get_us_regions():把这些()放在没有参数的方法上并不是惯用的。
  • first():在没有参数的调用上编写它们也不是惯用的。
  • results = {}:我已经用CR写了很多关于这个主题的文章,所以我只给出链接:用Ruby进行函数编程
  • # Important URLs:不确定是否重要到值得评论:-)
  • Nokogiri::HTML(...) ... long expression。表达式可以无尾链接,您必须决定何时中断并给出有意义的名称。我至少把它分解成两个子表达式。
  • gsub('http://','').gsub('.craigslist.org',''):使用模块URI代替手动操作URL。
  • results[area["hostname"]][:stateabbrev]:同样,这种表达式的函数式方法使它们更加简洁和清晰。
  • return results:明确的returns不是惯用的。
  • def get_us_regions。当一个方法如此琐碎而使其可配置时,请在这里给出这个国家作为参数-> def get_regions(country_code)

现在我是怎么写这个方法的。首先,我会使用,这是一个优秀的库,有许多核心中没有提供的很酷的抽象:

代码语言:javascript
运行
AI代码解释
复制
require 'uri'
require 'nokogiri'
require 'net/http'
require 'json'
require 'facets'

module CraigsList
  SitelistUrl = 'http://www.craigslist.org/about/sites'
  GeospatialUrl = 'http://www.craigslist.org/about/areas.json'

  # Return hash of pairs (hostname, {:name, :state, :stateabbr, :latitude, :longitude})
  # for US regions in craigslist.
  def self.get_regions(country_code)
    doc = Nokogiri::HTML(Net::HTTP.get(URI(SitelistUrl)))
    usregions = doc.search("a[name=#{country_code}]").first.parent.next_element.search('a')
    state_info = usregions.mash do |usregion|
      hostname = URI.parse(usregion.attr('href')).host.split(".").first
      state = usregion.parent.parent.previous_element.content
      info = {name: usregion.content, state: state}
      [hostname, info] 
    end

    areas = JSON.parse(Net::HTTP.get(URI(GeospatialUrl)))
    geo_info = areas.slice(*state_info.keys).mash do |area|
      info = {stateabbrev: area["region"], latitude: area["lat"], longitude: area["lon"]}
      [area["hostname"], info] 
    end

    state_info.deep_merge(geo_info)
  end
end

你提到你写了Javascript代码。函数式方法的好处是,代码在任何语言中都是相同的(不包括语法差异)(如果它具有最小的功能能力)。在JS中(尽管FP样式对Coffeescript更友好)和下划线 (+自定义抽象为mixins),您可以编写相同的代码。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/27832

复制
相关文章
R计算mRNA和lncRNA之间的相关性+散点图
我们在做表达谱数据分析的时候,经常需要检测基因两两之间表达的相关性。特别是在构建ceRNA网络的时候,我们需要去检查构成一对ceRNA的mRNA和lncRNA之间的表达是否呈正相关。前面给大家分享过R计算多个向量两两之间相关性,今天小编就给大家分享一个实际的应用案例,用R去批量的检测大量mRNA跟lncRNA之间表达的相关性,并绘制散点图。
生信交流平台
2022/09/21
8180
R计算mRNA和lncRNA之间的相关性+散点图
如何快速分析样本之间的相关性(主成分分析):Clustvis
首先给大家介绍一下主成分分析(PCA)的定义,PCA是一种通过正交变换将一组可能存在相关性的变量转换为不相关的变量的统计方法,这些转换后的变量就被称为主成分(来自维基百科)。而PCA的主要作用包括但不限于:方便数据可视化、数据降维等等。
用户6317549
2019/09/24
6K0
如何快速分析样本之间的相关性(主成分分析):Clustvis
强大的数据相关性分析
在数据分析中,有一种分析就是相关性的分析,所谓的相关性的分析就是 “不同现象之间相互相影响的关系叫相关性分析”,比如商场折扣和销量的 的分析,我们可以通过相关性分析,来判断折扣和销量之间的相关性有多强,多少折扣是销量最大的折扣,再比如孩子的身高和体重是否有相关性,标准的孩子身高和提升多多少。
王佩军
2020/07/24
2K0
强大的数据相关性分析
核心网络生命力和网络特征之间的相关性
核心网络活力(CWV)是Google认为是衡量网络体验质量的最重要指标的指标。识别和优化CWV问题的过程通常是被动的。网站所有者决定使用哪种技术或查看哪种指标通常是通过反复试验而不是经验研究来决定的。可以使用新技术来构建或重建站点,只是发现站点在生产中会导致UX问题。
海拥
2021/08/23
4340
如何提高Elasticsearch搜索的相关性
首先需要了解什么是相关性?默认情况下,搜索返回的结果是按照 相关性 进行排序的,也就是最相关的文档排在最前。相关性是由一个所谓的打分机制决定的,每个文档在搜索过程中都会被计算一个_score字段,这是一个浮点数类型,值越高表示分数越高,也就是相关性越大。
用户7634691
2021/03/18
1K0
相关性分析的五种方法有哪些_数据相关性分析
相关分析(Analysis of Correlation)是网站分析中经常使用的分析方法之一。通过对不同特征或数据间的关系进行分析,发现业务运营中的关键影响及驱动因素。并对业务的发展进行预测。本篇文章将介绍5种常用的分析方法。在开始介绍相关分析之前,需要特别说明的是相关关系不等于因果关系。
全栈程序员站长
2022/11/15
20.9K0
相关性分析的五种方法有哪些_数据相关性分析
Python 数据相关性分析
在我们的工作中,会有一个这样的场景,有若干数据罗列在我们的面前,这组数据相互之间可能会存在一些联系,可能是此增彼涨,或者是负相关,也可能是没有关联,那么我们就需要一种能把这种关联性定量的工具来对数据进行分析,从而给我们的决策提供支持,本文即介绍如何使用 Python 进行数据相关性分析。 关键词 python 方差 协方差 相关系数 离散度 pandas numpy
全栈程序员站长
2022/06/27
8080
Python 数据相关性分析
操纵相关性
可以看到,前面的4个细胞的4个基因都是0,在稀疏矩阵里面的0以小数点表示,如下所示是:
生信技能树
2022/12/16
3610
操纵相关性
相关性检验
利用 R 进行数据挖掘,数据来源于著名的 state.x77 数据集。这个数据集提供了美国 50 个州在 1997 年人口、收 入、文盲率、预期寿命、谋杀率和高中毕业率、气温以及土地面积的数据。通过数据搜集的信息,想知道哪些因素与谋杀率相关性较高。
生信喵实验柴
2022/10/25
3780
决策树和相关性
分类,指的是根据事物特征,推测类别的过程。 特征是我们观察到的现象,或者是已知的数据。 类别是我们根据特征,将事物做分类的结果。
楚客追梦
2023/05/04
6970
决策树和相关性
相关性分析和相关性分析可视化常用方法汇总
上面还有一个缺陷,没有给出显著性检验,默认的cor.test只能对两个变量进行显著性检验,比如:
邓飞
2022/01/04
2.3K0
相关性分析和相关性分析可视化常用方法汇总
如何合理的展示相关性分析结果??
如果是做肿瘤研究的,TCGA的数据分析,有很多在线工具是可以直接出图的,比如TIMER和GEPIA。上图的绘制,可以使用ggscatterstats函数,搜狗|微信 搜索一下,有很多现成的代码,就不多介绍了。
DoubleHelix
2021/11/01
1.6K0
如何合理的展示相关性分析结果??
R计算多个向量两两之间相关性
我们知道R里面计算两个数值向量之间的相关性用cor函数,而检验是否显著相关用cor.test。例如
生信交流平台
2022/09/21
7120
R计算多个向量两两之间相关性
转录和蛋白水平的表达量相关性如何
我在生信技能树的教程:《你确定你的差异基因找对了吗?》提到过,必须要对你的转录水平的全局表达矩阵做好质量控制,最好是看到标准3张图:
生信技能树
2021/10/12
1.9K0
R 相关性分析
R 相关性分析 1. 相关性矩阵计算: 加载mtcars数据 > setwd("E:\\Rwork") > data("mtcars") > head(mtcars) mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4 Wag 21.0 6 160 11
用户1359560
2018/08/27
1.3K0
R 相关性分析
相关性分析返回相关性系数的同时返回p值
可以看到是20个m6a基因,以及 1.5万个lncRNA的表达量矩阵,而且样品数量是500个;
生信技能树
2022/03/03
7530
人才盘点中的数据相关性分析
我们在做人力资源各项工作的目的都是为了可以支持业务的绩效,提升业务的绩效,不管是在招聘,培训,绩效等工作,但是在人力资源的工作中,我们很难直接的去和业务的绩效相关联,都是间接的支持业务的相关绩效,所以在人力资源的工作中我们一直在探索如何找出和有业务最相关的一些因素。 我们从人才发展和能力维度来分析如何通过数据分析的方法来找出业务业绩最相关的那个能力。 要做这个分析首先需要了解的一个概念就是“数据相关性”,所谓的数据相关性是两个变量之间的数据关系,这个数据关系分为两种正相关:Y数据随着X数据的增大而增大,系数K 是个正值负相关:Y 数据随着X的增大而减小,系数K是个负值
王佩军
2022/09/28
5950
皮尔逊相关性系数和热力图
特征选择是一个重要的“数据预处理”过程,在实现机器学习任务中,获得数据后通常先进行特征选择,此后再训练学习器。[1]
烤粽子
2021/07/07
2.2K0
相关性的疑问2020.8.7
3、为了缩小变化程度,平均前后5个月数量再进行同比分析。仿佛有了时间的延迟,但又像是变化比例不一样造成的。
用户7138673
2022/09/21
2270
相关性的疑问2020.8.7
相关性分析方法怎么选择_多个因素相关性分析
  有时候我们根据需要要研究数据集中某些属性和指定属性的相关性,显然我们可以使用一般的统计学方法解决这个问题,下面简单介绍两种相关性分析方法,不细说具体的方法的过程和原理,只是简单的做个介绍,由于理解可能不是很深刻,望大家谅解。
全栈程序员站长
2022/09/20
1.8K0

相似问题

如何让Selenium IDE Test停止并等待用户操作?

158

Selenium IDE记录不工作

23

Selenium IDE 2.6错误记录

12

使用Selenium IDE记录搜索功能

37

使用selenium IDE记录鼠标移动

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文