第一个爬虫

来源:互联网 发布:js array find方法 编辑:程序博客网 时间:2024/05/21 10:53
本爬虫主要以Richard Lawson所写的《Web Scraping with Python》(中文名是用Python写网络爬虫)的前两章内容为主。
1.环境:MacOS+Sublime Text3
2.爬取网站:http://example.webscraping.com/index/13.网站内容:一个用于学习爬虫的英文网站,网站的内容为200多个国家的详细信息,每个国家一个网页。
4.爬虫实现的功能:从任意一个国家的网页/或者站点地图SiteMap开始,爬取所有国家网页上的信息,包括面积,人口,首都,货币等待,并将所有信息存入CSV文档。
步骤:step1.从初始URL地址获取所有国家网页的URL地址
     step2.根据URL地址,逐个读取每个国家网页的HTML页面,并爬取所需信息
     step3.将所需信息写入CSV文档。
思路拆分:1.step1需要从初始URl地址下载对应HTML文档,本例通过Download()函数实现。之后需要从HTML网页上爬取链接,本例分别用两种方法实现。
          第一种是从网站提供的SiteMap获得,通过sitemap_crawler()函数实现;
                     第二种是从任意一个国家的网页读区其邻国的方式获取,通过link_crawler_bs4_neighbours()函数实现。
                  2. step2需要从每个国家的HTML网页读区所需信息,本例也用两种方法实现。
                     第一种是用Python模块Beautiful Soup4,通过scraper_bs4()函数实现;
                     第二种是用Python模块Lxml,通过scraper_lxml()函数实现;
                 3. step3 用Python模块CSV实现
# !/usr/bin/env python# coding = UTF-8
 import urllib2import refrom bs4 import BeautifulSoupimport csvimport lxml.htmlimport sysimport timeimport urlparse
#列表fields的元素为需要从国家网页获取的信息fields = ['country','capital','area','population','continent','languages','currency_code','currency_name','postal_code_format','postal_code_regex','phone','iso','neighbours','tld']
#Download函数从给定的URL地址下载HTML,函数通过Python模块urllib2实现
#首先调用urbllib2模块的urlopen函数,该函数读区给定url地址,并返回一个类似文件的对象或者是request类型对象
#调用该对象的read()函数,函数返回URL对应的HTML内容,保存在变量html
#函数执行完返回html 
def Download(url = None):'this function downloads contents of html webpage with given URL'request = urllib2.urlopen(url)html = request.read()return html
#sitemap_crawler函数从给定的网站地图SiteMap读取网站所有的链接
#URL_list列表用来存储读取的链接,以sitemap的URL地址初始化
#该函数首先调用Download函数根据sitemap的URL读取对应HTML,Download函数会把html返回
#接着本函数调用re模块的findall函数,findall函数根据给定的正则表达式从html内筛选链接,并以列表形式返回
#函数结束并返回所有的link,以列表的形式
def sitemap_crawler(url):'this function scrawl the webpage starting from the given sitemap, and it will returns all the links saved in this webpage in an list'URL_list = [url]html = Download(url)# download html from given url of sitemaplinks = re.findall('<loc>(.*?)</loc>',html)# extract all links from sitemap webpagereturn links
# link_crawler_bs4_neighbours函数从每个国家的网页读取其邻国网页的链接,将所有链接以列表形式返回
# 该函数有一个问题是,不能将所有国家的链接全部读取,因为并不是所有国家物理上都通过陆地连接,所以从任意一个国家开始读区,只能读区该国家所在板块内的国家
# URL_list用来存取所有读取的链接,seen_URL也用来存取所有链接,两者都以给定的国家网页URL初始化
# 函数首先调用Download函数下载初始URL对用HTML,并调用BeautifulSoup函数解析,解析出Bs4格式的html存在变量soup内
# 之后通过find和findall函数逐步锁定包含相对URL的标签,以列表形式links_tags返回
# 相对URL以属性值的形式存储在href属性所在的<a>标签内,bs4的Html文档内tag的属性操作方式与字典相同
# 最终通过[]键值的形式获得相对URL
# 之后再通过urlparse模块的urljoin函数将相对URL转换为绝对URL
# 如果该URL为第一次见,存入两个列表
# 函数结束,返回seen_URL
def link_crawler_bs4_neighbours(url):'this function scrawls the link one by one by searching abstract or realative URL in HTML in given URL of certain country''but there are limitations of this function, because we can not track all country from one country by looking fro neighbours''from the world map, not all country holds together on continent'URL_list = [url]seen_URL = [url]while URL_list:URL = URL_list.pop()html = Download(URL)soup = BeautifulSoup(html,'html.parser')links_tags = soup.find('tr',{'id':'places_neighbours__row'}).find_all('a')print 'searching URL:%s' % URLfor link_tag in links_tags:link = link_tag['href']print 'find:',linklink = urlparse.urljoin('http://example.webscraping.com',link)if link not in seen_URL and link != 'http://example.webscraping.com/iso//':URL_list.append(link)seen_URL.append(link)print "add :",linkprint '\n'return seen_URL
# 该函数用BeautifulSoup模块来从html中抓取所需信息
# 函数首先调用Download函数读取某一国家网页的URL,并下载HTML
# 列表Info初始化为空,每读取的一个数据都将作为元素存放入其中
# BeautifulSoup将html网页转化为BeautifulSoup形式的html并存入变量
# 之后通过find函数,以标签名,属性名,属性值逐步搜索到所需的标签内容依次存入变量value,并添加到列表Info
# 函数结束返回列表Info def scraper_bs4(url):'this function scrawl all the information from the webpage and save it in a CSV file'html = Download(url)Info = []soup = BeautifulSoup(html,'html.parser')for field in fields:value = soup.find('tr',{'id':'places_%s__row'%field}).find('td',{'class':'w2p_fw'}).string Info.append(value)if field == 'country':print 'writing %s' % valuereturn Info
# scraper_lxml函数同样先调用Download函数下载html
# 再调用lxml.html.fromstring函数将html转换为lxml形式的内容
# 之后通过cssselector选择器来筛选所需内容,依次存入变量value
# 最后返回info def scraper_lxml(url):'this function scrawl all the information from the webpage and save it in a CSV file'html = Download(url)Info = []tree = lxml.html.fromstring(html)for field in fields:value = tree.cssselect('tr#places_%s__row > td.w2p_fw' % field)[0].text_content()Info.append(value)if field == 'country':print 'writing %s' % valuereturn Info
def main():root_url = 'http://example.webscraping.com/index/1'links = link_crawler_bs4_index(root_url)print 'length of links: %d',len(links)writer1 = csv.writer(open('country_info_bs4.csv','w'))writer1.writerow(fields)start1 = time.time()for link in links:row = scraper_bs4(link)writer1.writerow(row)end1 = time.time()print 'bs4 writing finished in %.2f seconds' % (end1-start1)writer2 = csv.writer(open('country_info_lxml.csv','w'))writer2.writerow(fields)start2 = time.time()for link in links:writer2.writerow(scraper_lxml(link))end2 = time.time()print 'lxml writing finished in %2.f seconds' % (end2-start2)if __name__ == '__main__':main()



0 0
原创粉丝点击