动态网页数据挖掘一例
来源:互联网 发布:mac 命令行查找文件夹 编辑:程序博客网 时间:2024/06/06 04:34
这次的网址是:中国土地市场网
我需要这个网站里面每个链接点开之后的信息,并将这些信息整合到一个csv文件中。网页一共有200页,每页30条记录,共计6000条记录。
#coding:utf8from bs4 import BeautifulSoup as spimport urllib2import pandas as pdfrom pandas import DataFrame as dfimport osimport reimport timefrom selenium import webdriverdef alpha(x): return filter(str.isalpha,x)def num(x): return filter(str.isdigit,x)
我们以第一条记录点开后的网址为例:第一条记录,确定存放最终结果的DataFrame如下:
cols=['宗地标识:','宗地编号:','所在行政区:','宗地座落:','土地面积:','土地他项权利人证号:','土地使用权证号:','土地抵押人名称:','土地抵押人性质:','土地抵押权人:','抵押土地用途:','抵押土地权属性质与使用权类型:','抵押面积(公顷):','评估金额(万元):','抵押金额(万元):','土地抵押登记起始时间:','土地抵押登记结束时间:']a=df(columns=cols,index=range(30))
因为数据均为中文,所以记得要在程序开头加上utf8编码,不然会乱码(其实乱码也没有关系,存入csv文件里面之后改一下编码格式依然是可读的)
首先,我们先来写一个函数,这个函数会将一个具体链接的网址中数据抓出来,并写入一个DataFrame中去。因为每条记录所在的网址打开后比较简单,是一个静态的html,没什么多说的:
def SingleRecord(trs,count,daf): ''' Return the dataframe after a new record is detected 这里的trs代表着html网页里面的tr元素的合集,由main函数传入,daf就是目标DataFrame,count是记录的条数,从0到5999 ''' tmp=[] for cnt,tr in enumerate(trs): rec=tr.text.split('\n') if cnt==0: pass if cnt==1: tmp.append(rec[2]) tmp.append(rec[4]) if cnt==2: tmp.append(rec[3]) if cnt>2: tmp.append(rec[2]) tmp.append(rec[4]) daf.ix[count%30]=tmp if (count+1)%30==0: daf.to_csv(r"C:\Users\turmoil\Desktop\fuck\%s.csv"%(str((count+1)/30)),encoding='utf8') daf=df(columns=cols,index=range(30)) return daf
def PageUrls(html): ''' get the effective urls in a page, it will return a list,此处的html即为包含30条记录地址的网页源码 ''' pat = re.compile(r'href="([^"]*)"') #过滤出里面存在的记录链接 base="http://www.landchina.com/" soup=sp(html) table=soup.find('table',id="TAB_contentTable") trs=table.findAll('tr') result=[] for tr in trs: h=pat.search(str(tr)) if h: href=h.group(1) result.append(base+href.replace(";","&")) return result
现在,我们可以根据记录的合集网页来获取每一条记录的具体地址了,并且可以通过地址来获取每一条记录。主要的事情看上去做完了,其实并没有。我们还需要遍历第1页到第200页中的所有页数,这个会比较麻烦,因为网页是动态的,所以需要处理一下JavaScript。从当前页跳到下一页时,需要点击页面上的“下页”
cur_page=1 for i in range(cur_page,200): browser.find_element_by_link_text("下页").click() cont=browser.page_source
到了这里,基本工作差不多都完成了,但是由于网页或者别的问题,在抓取过程中会经常遇到各种各样的错误。这个时候从断点处继续工作会比较重要,而发生断点的时候可能会在比较后面的页数,例如150页。如果用selenium模拟点“下页”来完成这个动作,需要点100多次,非常不方便。这个时候可以调用selenium的JavaScript处理方法来直接跳转到第150页,具体如下:
browser=webdriver.Chrome()loc="http://www.landchina.com/default.aspx?tabid=351"browser.get(loc)go=browser.find_element_by_xpath("//input[@type='button']") browser.execute_script("QueryAction.GoPage('TAB',123,200)", go) # go按钮的JS代码是在网页的源码中分析出来的,在点击go这个按钮的时候,里面其实是传入了一个JS函数<input type="button" value="go" onclick="QueryAction.GoPage('TAB',this.previousSibling.value,200)"/>,因此可以模拟直接执行这个函数来进行页面跳转content=browser.page_source
当断点出现需要重新开始时,载入之前的工作,
def reload(url): file_list=os.listdir(r"C:\Users\turmoil\Desktop\fuck") if file_list==[]: end=1 else: file_list=[int(num(x)) for x in file_list] end=max(file_list)+1 cycle=(end-1)/10 browser=webdriver.Chrome() browser.get(url) print end-1,cycle if cycle==0: return browser,end for i in range(cycle): try: browser.find_elements_by_link_text("...")[-1].click() except: time.sleep(5) browser.refresh() browser.find_elements_by_link_text("...")[-1].click()# time.sleep(5) if str(end)[-1]!='1': browser.find_element_by_link_text(str(end)).click() return browser,end
def main(url,daf): browser,end=reload(url) content=browser.page_source urls=PageUrls(content) t=webdriver.Chrome() cur_page=end for k,web in enumerate(urls): t.get(web) html=t.page_source soup=sp(html) table=soup.find('table',id="FormView21_1") if table==None: time.sleep(8) t.refresh() html=t.page_source soup=sp(html) table=soup.find('table',id="FormView21_1") trs=table.findAll('tr') daf=SingleRecord(trs,k+(cur_page-1)*30,daf) for i in range(cur_page+1,201): browser.find_element_by_link_text("下页").click() cont=browser.page_source try: ur=PageUrls(cont) except AttributeError: time.sleep(20) browser.refresh() time.sleep(8) browser.refresh() cont=browser.page_source ur=PageUrls(cont) cur_page=cur_page+1 for j,w in enumerate(ur): t.get(w) html=t.page_source soup=sp(html) table=soup.find('table',id="FormView21_1") if table==None: time.sleep(20) t.refresh() time.sleep(8) t.refresh()# t.get(w) html=t.page_source soup=sp(html) table=soup.find('table',id="FormView21_1") trs=table.findAll('tr') daf=SingleRecord(trs,(i-1)*30+j,daf) print (i-1)*30+j else: trs=table.findAll('tr') daf=SingleRecord(trs,(i-1)*30+j,daf) browser.quit() t.quit()
其实这里面对网页出错的处理并不好,因为只是重新加载了一次。实际运行过程中可能需要加载多次。这个时候判断情况需要更改一下,用While循环做判断的话效率会更高。
if __name__=="__main__": url="http://www.landchina.com/default.aspx?tabid=351" main(url,a)
0 0
- 动态网页数据挖掘一例
- 数据挖掘基础一
- 数据挖掘笔记一
- 数据挖掘实验(一)
- 网页数据动态绑定
- 数据挖掘笔记(一)
- 数据挖掘随笔记录一
- 数据挖掘笔记(一)
- 数据挖掘学习指引<一>
- 数据挖掘学习篇一
- 数据挖掘导论 (一)
- 数据挖掘整理(一)
- 数据挖掘笔记(一)
- 数据挖掘学习笔记一
- 数据挖掘学习(一)
- 【数据挖掘笔记一】引论
- 数据挖掘算法之关联规则挖掘一apriori算法
- 一、什么是动态网页、网站?
- MyBatis的Error setting null for parameter #1 with JdbcType OTHER异常
- C++中静态成员变量和静态成员函数
- 新浪微博第三方客户端
- 将Ceilometer默认的MongoDB改为MySQL
- leetcode:Find Peak Element
- 动态网页数据挖掘一例
- json和xml解析
- 基于Qt的sqlite编程
- 计数排序,基数排序和桶排序
- 完全开启Eclipse代码自动提示(包括变量名称)
- typeof运算符及实现jquery中的addClass,removeClass,hasClass
- Rails3: 新的 Metal 機制
- iOS 开发中的设计模式
- 嵌入式菜鸟算法③---链表操作