我們都知道很多數據都可以通過爬蟲進行爬取,如果我們爬取的是一個簡單的頁面,那么很輕松就可以實現了,如果要爬取動態(tài)頁面,那么怎么辦呢?
比如說我們要爬取東方財富網站上面的這些股票信息:
http://quote.eastmoney.com/center/list.html#10_0_0_u?sortType=C&sortRule=-1
但是我們查看源碼的時候卻看不到任何關于股票信息的數據,可以看出這些股票數據是異步加載的,果斷F12打開chrome開發(fā)者工具,在Network選項中查看,如果沒有的話可以F5刷新一下頁面就出來了。
然后點擊那個異步的api,會新打開一個頁面,出現以下的數據:
var C1Cache={quotation:["0000011,上證指數,3166.98,170854125568,13.89,0.44%,876|201|246|142,1380|270|360|204","3990012,深證成指,10130.12,215605108736,74.55,0.74%,876|201|246|142,1380|270|360|204"]}
本以為是一個json的數據,但是服務端傳來的是一個js變量,值類似一個json數據,這應該是為了開發(fā)的方便,但是我們要的是json的數據,所以需要過濾一下,split("=")然后取右邊的字符串就行了,但是需要注意下,這個右邊的不是json數據,注意json的key需要有雙引號(在java中和python中),或許在js下有沒有都可以吧,所以我們在java中還需要replace一下,這樣才是一個json字符串,然后轉換成json對象,可以用jackson的 objectmapper,反正方法很多。然后把這些數據持久化到數據庫就可以了,這樣我們就實現了一些動態(tài)頁面的爬取。
但是這里需要注意的就是,有些網站不允許你跨域去訪問,即使你通過偽裝服務端還是有對策來防止你直接調用api,那么這個時候就需要用另一種方法,webmagic selenium,這個的原理就是,先運行一個瀏覽器內核去加載這個頁面,等到整個頁面加載完后再獲取html代碼,然后進行處理。
比如說我們要爬取上交所的浦發(fā)銀行這支股票背后的公司信息,http://www.sse.com.cn/assortment/stock/list/info/company/index.shtml?COMPANY_CODE=600000
我們查看異步加載的api的時候,發(fā)現不允許你直接的訪問這個api,所以只能用第二種方法了。
下面是項目的依賴:
compile 'us.codecraft:webmagic-core:0.5.3'
compile('us.codecraft:webmagic-extension:0.5.3')
compile 'org.seleniumhq.selenium:selenium-java:2.8.0'
compile group: 'us.codecraft', name: 'webmagic-selenium', version: '0.5.2'
源碼如下:
public class CompanyProcessor implements PageProcessor {
private Site site = Site.me().setRetryTimes(3).setSleepTime(1000).setTimeOut(3000)
.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36");
public void process(Page page) {
WebDriver driver = new ChromeDriver();
driver.get("http://www.sse.com.cn/assortment/stock/list/info/company/index.shtml?COMPANY_CODE=600000");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebElement webElement = driver.findElement(By.id("tableData_stockListCompany"));
// WebElement webElement = driver.findElement(By.xpath("http://div[@class='table-responsive sse_table_T05']"));
String str = webElement.getAttribute("outerHTML");
System.out.println(str);
Html html = new Html(str);
System.out.println(html.xpath("http://tbody/tr").all());
String companyCode = html.xpath("http://tbody/tr[1]/td/text()").get();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String dateString = html.xpath("http://tbody/tr[3]/td/text()").get().split("/")[0];
String stockCode = html.xpath("http://tbody/tr[2]/td/text()").get().split("/")[0];
String name = html.xpath("http://tbody/tr[5]/td/text()").get().split("/")[0];
String department = html.xpath("http://tbody/tr[14]/td/text()").get().split("/")[0];
System.out.println(companyCode);
System.out.println(stockCode);
System.out.println(name);
System.out.println(department);
driver.close();
}
public Site getSite() {
return site;
}
public static void main(String[] args) {
Spider.create(new CompanyProcessor())
.addUrl("http://www.sse.com.cn/assortment/stock/list/info/company/index.shtml?COMPANY_CODE=600000")
.thread(5)
.run();
}
}
這里面有一些webmagic的知識,如果不熟悉的可以看一下中文文檔,因為這個爬蟲框架是中國人寫的,所以中文文檔很詳細http://webmagic.io/docs/zh/
這里注意一下這行代碼:
WebDriver driver = new ChromeDriver();
如果要讓代碼運行成功需要下載一個chromedriver,如果你是windows可以去這個網址去下https://chromedriver.storage.googleapis.com/2.25/chromedriver_win32.zip,雖然是32位的但是64位也可以用,如果不行的話或者你是其他OS,可以去官網下https://chromedriver.storage.googleapis.com/index.html?path=2.27/
這里為什么不直接推薦去官網下載最新的呢?因為我之前用過,最新的在我的兩個電腦上的windows系統(tǒng)都出現了問題。現在完成后解壓放在C:\Windows\System32目錄下,或者設置一下環(huán)境變量都行。
然后就可以運行了,之后的就是去提取一些數據或者url了,就像處理靜態(tài)頁面一樣了。