Java使用Selenium 爬取中国知网
所需Jar包
中国知网的网页结构,我就不在这里赘述了,自己去看,这里我操作的是爬取博硕论文,只抓取前十页
当Selenium无法调取ChromeDriver时可参考以下建议:
1.chromedriver是否与当前Chrome版本兼容
2.chromedriver是否放置在Chrome安装目录下
3.chromedriver是否配置环境变量
4.selenium版本是否与chromedriver相冲突,换个版本测试
附上代码
package com.qdcz.plugins;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
import java.util.Set;
public class Test {
public static void main(String args[]) throws Exception {
//调用chrome driver
System.setProperty("webdriver.chrome.driver", "C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe");
//调用chrome
WebDriver driver = new ChromeDriver();
//调整高度
((ChromeDriver) driver).executeScript("window.scrollTo(0, document.body.scrollHeight);");
//获取网址
((ChromeDriver) driver).get("http://epub.cnki.net/KNS/brief/result.aspx?dbprefix=CMFD");
//高级搜索
WebElement high = driver.findElement(By.xpath("//*[@id=\"1_3\"]/a"));
high.click();
Thread.sleep(1000);
//定位元素
WebElement in = ((ChromeDriver) driver).findElementByName("txt_1_value1");
//定义搜索内容
String searchWord = "";
searchWord = "基因芯片";
//发送搜索内容
in.sendKeys(searchWord);
((ChromeDriver) driver).findElementByXPath("//*[@id='ddSubmit']/span").click();
((ChromeDriver) driver).findElementByXPath("//*[@id='btnSearch']").click();
Thread.sleep(2000);
//清除分类获得所有
((ChromeDriver) driver).findElementByXPath("//*[@id='XuekeNavi_Div']/div[1]/input[1]").click();
((ChromeDriver) driver).findElementByXPath("//*[@id='B']/span/img[1]").click();
Thread.sleep(2000);
//分割符
System.out.println("-----------------------");
//定位iframe
WebElement iframe = driver.findElement(By.id("iframeResult"));
//也可直接这样写((ChromeDriver) driver).switchTo().frame("id=iframeResult");
//线程休眠
Thread.sleep(2000);
for (int i = 0; i <10; i++) {
//获取窗口
String now_handle = driver.getWindowHandle();
Set<String> all_handles = driver.getWindowHandles();
//判断窗口是否一致
for (String handle : all_handles) {
if (handle != now_handle) {
driver.switchTo().window(handle);
((ChromeDriver) driver).switchTo().frame(iframe);
//选择50页
WebElement btn = ((ChromeDriver) driver).findElementByXPath("//*[@id=\"id_grid_display_num\"]/a[3]");
btn.click();
//获取页面内容
//String content=driver.getPageSource();
//System.out.println(content);
//获取iframe元素内容直至tr
List<WebElement> tb = driver.findElements(By.xpath("//*[@id=\"ctl00\"]/table/tbody/tr[2]"));
for (WebElement t : tb) {
List<WebElement> tbod = t.findElements(By.tagName("tbody"));
for (WebElement tr : tbod) {
List<WebElement> td = tr.findElements(By.tagName("tr"));
td.remove(0);
for (WebElement tds : td) {
List<WebElement> tdss = tds.findElements(By.tagName("td"));
String title = tdss.get(1).getText();
String author=tdss.get(2).getText();
String college=tdss.get(3).getText();
String year=tdss.get(4).getText();
System.out.println(title+"--"+author+"--"+college+"--"+year);
}
}
}
}
}
//线程休眠
Thread.sleep(1000);
WebElement nextBtn=((ChromeDriver) driver).findElementByXPath("//*[@id=\"Page_next\"]");
nextBtn.click();
}
//关闭driver
driver.close();
}
}
附上结果
我在想如何抓取全,中国知网的论文题目,作者,导师等等信息,一直没有什么大的思路进展,因为中国知网有Piwik.js写了追踪函数,其次的url参数里有时间加密,所以获取url也不能正确的保证访问到原网页,这让我很是苦恼,目前已知的有一种时间 参数时Unix时间格式,具体页面后面的我不知道是如何进行加密的,破解不了。另外有一种思路是通过post请求大学页面抓取,这是可行的,但与我想要的数据有差异,故不尝试。
诸位有什么好的想法或建议,可以告诉我,一起交流~
本文在一定程度上借鉴了https://blog.csdn.net/hensonwells/article/details/77126819这篇文章(python)的思想,有兴趣的同学可以去看看。
如果你想进一步抓取知网的信息(非论文)可以看看我写的另一篇文章
https://blog.csdn.net/qq_40244755/article/details/88689814