Skip to content

xperiatrix/dwell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Just Dwell It.

     Dwell is an application which can make it easier to find the good places to rent and to dwell in Xi'an City according to a few steps on Data Visualization. Now I'm going to code for learning new skills, sharing tips, and providing values for the city in my way. I hope you'll gonna like this.

Make the Plan.

  • There're 3 main steps in server-project. Fetch DataSource + Parse DOM + Save Records.
  • 基于高德地图SDK,由地址信息反向解析获取坐标,剔除数据库脏数据后,借助高德开放平台的数据可视化接口予以显示。
  • Manage the development in Trello including push-notifications from Continuous Integration server.
  • Base on Java Spring Boot as backend.   Amazon Corretto 8 (An OpenJDK-8 for avoiding the affairs of copyright in legal)
  • Base on React.js as frontend for displaying.

Programming Details.

Summary.

         由于Dwell用到了网页爬虫来获取页面数据,python这两年太火热了,原本一开始也是打算使用Python的,但目前还没写过Python,考虑到时间成本,想想不如用Java来实现后端,顺便能把Java语言通过项目好好实践一下。我在后端项目开发的过程中,对爬虫很感兴趣,也阅读了大量爬虫相关的内容,尝试对爬虫获取数据这部分业务功能进行有针对性优化,结合项目的实现思路,写完代码后在这里也记录一下,如有错误,请予以指正。

  • 爬虫是基于【图论】的遍历
        可能看到【图】这个数据结构,人们脑中第一印象就是深度优先算法(DFS 简单理解是一条路走到底,走不动的时候再返回回去,从分叉的路接着往下走,再次走到底,循环这样的方法,直到把所有的分叉路全部走完结束)或者广度优先算法(BFS 简单理解是尽可能‘广’地把每个节点直接相连的几个节点访问一遍,直到直接相连的节点被遍历完,再遍历间接相连的节点,循环使用这样的方法,直到把所有节点访问完)。关于图,还有有向图,无向图的区分(微博、朋友圈的好友关系、可能认识的人等)

  • 爬虫要避免访问重复的页面(HashTable)
        使用HashMap这个数据结构,用来存储已经访问过的url,因为页面url是唯一的。但在Dwell项目中,url不直接作为key使用,而是先md5处理一下,使原始很长的url哈希为16字节大小,3000条数据的key任何电脑都可以直接读取。如果数据量大到上亿条时,不建议使用HashMap,因为Map有装载因子,虽然天然支持动态扩容(基于链表),实际使用时内存占用更大。这时可以考虑将访问记录分散在10000个文件中,每个文件最大500Mb, 让URL先hash再对10000去模运算,得到的结果就是url应保存的文件编号然后依次对10000个数据进行处理,这样即使单台机器内存只有1GB,也可以使用这种方法处理数据。(与load-balance的处理思路类似)

  • 爬虫实现过程中需要工程素养

    • 从0开始要实现一个爬虫,实际上综合考验着一个人对于计算机科学理论基础、算法能力、工程素养等很多方面。针对爬虫来解决的主要问题,清晰地定义是【如何在有限的时间内,尽可能多地获得更重要的网页信息?】 所以,尽管DFS与BFS都可以完成爬取任务,但显然在实际项目中BFS更多的会被优先选用(设想:给你一张报纸,你要发现今天的重大新闻,肯定会是先粗略地看一下每版的标题,再细看文章的),但是不全以偏概全,爬虫爬取数据的算法,更多情况应该是按照一个复杂的优先级队列,来按需分配下载页面的前后顺序的
    • TCP的通信成本太高(因为它的请求不是一条路走到底的),如果握手次数太多,爬虫的下载效率就降低了。大多数情况,爬虫是一台或者多台服务器组成的分布式系统,对于某个特定的网页,一般是被特定的一台或者几台机器访问的,它们应该是独立的下载服务器,单独就做fetching这一件事。
    • 页面数据的分析与URL的获取: 随着网页技术的发展,web上已经不再是纯静态数据了(HTML),更多的时候,是需要让浏览器打开页面,并运行一些脚本,动态生成数据展示的。这就需要我们动态的获取请求链接(javascript, ajax等),有时候还需要爬虫来模拟浏览器的环境访问url。因为页面上的脚本存在很多不规范的地方,所以,有极端的情况,需要浏览器内核工程师对页面进行解析。有时候爬虫没获取到数据,可能是没有成功解析网页上那些不规范的脚本程序。
    • 访问重复的页面: 如果有上千台服务器一起下载网页,那么维护一张统一的哈希表就不是一个容易的问题了。首先,这张哈希表可能非常大,大到一台机器根本存放不下,其次上千台机器同时要维护这张哈希表,那么存储这张哈希表的服务器的通信就成了整个爬虫系统的瓶颈。:
    • 该如何消除这样的瓶颈: 首先,使用哈希算法对url做hash,并对机器的数量取模,得到的结果就是该url对应的机器编号,以此明确每台机器的分工,也就是爬虫系统看到一个url时,就已经知道应该让第几号机器去爬取,避免了很多服务器看到一个url后,对同一个url作出是否需要下载的判断。 其次,在明确分工的基础上,减少通信次数,降低通信成本的开销,使用批处理,一次批量操作一大批哈希表更新的请求。(JVM的垃圾标记、回收算法思路雷同)
  • TODO: 还要注意 如何去反爬虫

GitHub Open API

# GitHub searching API list:
 
 {
     "current_user_url": "https://api.github.com/user",
     "current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
     "authorizations_url": "https://api.github.com/authorizations",
     "code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
     "commit_search_url": "https://api.github.com/search/commits?q={query}{&page,per_page,sort,order}",
     "emails_url": "https://api.github.com/user/emails",
     "emojis_url": "https://api.github.com/emojis",
     "events_url": "https://api.github.com/events",
     "feeds_url": "https://api.github.com/feeds",
     "followers_url": "https://api.github.com/user/followers",
     "following_url": "https://api.github.com/user/following{/target}",
     "gists_url": "https://api.github.com/gists{/gist_id}",
     "hub_url": "https://api.github.com/hub",
     "issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
     "issues_url": "https://api.github.com/issues",
     "keys_url": "https://api.github.com/user/keys",
     "label_search_url": "https://api.github.com/search/labels?q={query}&repository_id={repository_id}{&page,per_page}",
     "notifications_url": "https://api.github.com/notifications",
     "organization_url": "https://api.github.com/orgs/{org}",
     "organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
     "organization_teams_url": "https://api.github.com/orgs/{org}/teams",
     "public_gists_url": "https://api.github.com/gists/public",
     "rate_limit_url": "https://api.github.com/rate_limit",
     "repository_url": "https://api.github.com/repos/{owner}/{repo}",
     "repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
     "current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
     "starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
     "starred_gists_url": "https://api.github.com/gists/starred",
     "topic_search_url": "https://api.github.com/search/topics?q={query}{&page,per_page}",
     "user_url": "https://api.github.com/users/{user}",
     "user_organizations_url": "https://api.github.com/user/orgs",
     "user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
     "user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
 }

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages