牛骨文教育服务平台(让学习变的简单)
博文笔记

浅谈java及python爬虫

创建时间:2017-12-29 投稿人: 浏览次数:1161
爬虫,就是把你在网页上能看到的信息通过代码自动获取到本地的过程。 常用框架: java:webmagic,http://webmagic.io/docs/zh/ python:scrapy,http://blog.csdn.net/sunnyxiaohu/article/details/50787430
随着AJAX技术不断的普及,以及现在AngularJS这种Single-page application框架的出现,现在js渲染出的页面越来越多。对于爬虫来说,这种页面是比较讨厌的:仅仅提取HTML内容,往往无法拿到有效的信息。那么如何处理这种页面呢?总的来说有两种做法: 1.在抓取阶段,在爬虫中内置一个浏览器内核,执行js渲染页面后,再抓取。这方面对应的工具有Selenium、HtmlUnit或者PhantomJs。但是这些工具都存在一定的效率问题,同时也不是那么稳定。好处是编写规则同静态页面一样。 2.因为js渲染页面的数据也是从后端拿到,而且基本上都是AJAX获取,所以分析AJAX请求,找到对应数据的请求,也是比较可行的做法。而且相对于页面样式,这种接口变化可能性更小。缺点就是找到这个请求,并进行模拟,是一个相对困难的过程,也需要相对多的分析经验。
windows下主流浏览器都可以,linux服务器上只能无头浏览器,常用的例如phantomjs。
selenium python操作: dcap = dict(DesiredCapabilities.PHANTOMJS) #设置useragent dcap["phantomjs.page.settings.userAgent"] = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0)" " Gecko/20100101 Firefox/25.0 ") #根据需要设置具体的浏览器信息 browser = webdriver.PhantomJS(desired_capabilities=dcap) #封装浏览器信息
  1. browser.get(url) #访问url
  2. browser.find_element_by_xpath("//div[@id="nav_content_5"]/a") #元素定位
  3. browser.find_element_by_class_name("query").send_keys(u"百度") #元素定位并键入值(适用于搜索框)
  4. browser.find_element_by_class_name("oBtn").click() #元素定位并点击(常用)
  5. ActionChains(browser).move_to_element(element).perform() #鼠标悬停
  6. handles = browser.window_handles #获取当前全部窗口句柄集合
  7. browser.switch_to.window(browser.window_handles[1]) #跳转到某个窗口(适用于点击新开标签页)
  8. browser.find_element_by_link_text(“下一页”) #标签元素快速定位
  9. data = browser.page_source #获取页面源码

selenium java操作: WebDriver driver = new ChromeDriver();
  1. driver.get(url);
  2. driver.findElement(By.xpath("//*[@id="username"]")).sendKeys(userName);#定位元素键入值
  3. driver.findElement(By.xpath("//*[@id="btn-login"]")).click();#定位元素并点击
  4. new Actions(driver).moveToElement(driver.findElement(By.xpath("//*[@id="topPanel"]/ul/li[3]/a"))).perform(); #鼠标悬停
  5. String source = driver.getPageSource(); #获取页面源码

爬取细节: 可以通过xpath元素定位亦或是正则获取。
python: pattern = "<li>.*?<a href="(.*?)">(.*?)</a>.*?<span.*?>(.*?)</span>" data = browser.page_source contents = re.findall(pattern, data, re.S) #re.S作用:使用re.S参数以后,正则表达式会将这个字符串作为一个整体,而不只是单行匹配 for content in contents: #处理细节 #content[0],content[1],content[2分别表示第一,二,三个group
java: regex: String regexNumber = "&coNum=(.*?)&"; Pattern pattern = Pattern.compile(regexNumber,Pattern.DOTALL); Matcher matcher = pattern.matcher(url); while (matcher.find()){ #处理细节 #mather.group(0)表示匹配的整个字符串,mather.group(1)表示第一个group, #mather.group(2)表示第二个group } xpath: Html html = new Html(source); //获取单个数据 String name = html.xpath("[@id="custName"]/text()").toString(); //获取列表数据 List<String> strings = html.xpath("//*[@id="content"]/ul/li").all();
附:1.我对正则group的理解 一个()就是一个group 2.xpath简单获取方式 浏览器上右键审查元素,此时会定位到代码,再右键出来copy xpath就ok 2.java模拟chrome下载文件代码 String downloadFilepath = "D:\test\excel"; HashMap<String, Object> chromePrefs = new HashMap<String, Object>(); chromePrefs.put("profile.default_content_settings.popups", 0); chromePrefs.put("download.default_directory", downloadFilepath); ChromeOptions options = new ChromeOptions(); HashMap<String, Object> chromeOptionsMap = new HashMap<String, Object>(); options.setExperimentalOption("prefs",chromePrefs); options.addArguments("--test-type"); DesiredCapabilities cap = DesiredCapabilities.chrome(); cap.setCapability(ChromeOptions.CAPABILITY, chromeOptionsMap); cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); cap.setCapability(ChromeOptions.CAPABILITY, options); WebDriver driver = new ChromeDriver(cap); #-----------------------此处省略各种花里胡哨的操作----------------------- JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].click();",driver.findElement(By.xpath("//* [@id="content"]/div[1]/div[5]/input[1]"))); driver.findElement(By.xpath("//*[@id="content"]/div[1]/div[5]/input[1]")).click();

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。