23930
113 mins
用户态与内核态 JDK早期,synchronized 叫做重量级锁, 因为申请锁资源必须通过kernel, 系统调用
;hello.asm ;write(int fd, const void *buffer, size_t nbytes) section data msg db "Hello", 0xA len equ $ - msg section .text global _start _start: mov edx, len mov ecx, msg mov ebx, 1 ;文件描述符1 std_out mov eax, 4 ;write函数系统调用号 4 int 0x80 mov ebx, 0 mov eax, 1 ;exit函数系统调用号 int 0x80 CAS Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 (无重量锁)
126
1 min
WebMagic之Spider进阶 从解决问题开始吧。
问题描述:由于数据库的数据量特别大,而且公司没有搞主从读写分离,导致从数据库读取数据比较慢,而我需要从数据库查询出特定标识来拼url去抓。实际运行中就发现了一个有趣的现象。爬虫抓取的速度超过了我用scheduler给它推送url的速度,导致爬虫从scheduler获取不到url,同时此刻线程池所有线程都已停止。这个时候,根据Spider的机制是要退出调度循环的,从而终止Spider。从下面代码可以看出:(取自Spider的run方法):
while ((!(Thread.currentThread().isInterrupted())) && (this.stat.get() == 1)) { Request request = this.scheduler.poll(this); if (request == null) { if ((this.threadPool.getThreadAlive() == 0) && (this.exitWhenComplete)) { break; } waitNewUrl(); } else { Request requestFinal = request; this.threadPool.execute(new Runnable(requestFinal) { public void run() { try { Spider.
476
3 mins
爬虫框架WebMagic源码分析之Selenium webmagic有一个selenium模块,其中实现了一个SeleniumDownloader。但是感觉灵活性不大。所以我就自己参考实现了一个。
首先是WebDriverPool用来管理WebDriver池:
import java.util.ArrayList; import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import org.openqa.selenium.WebDriver; import org.openqa.selenium.phantomjs.PhantomJSDriver; import org.openqa.selenium.phantomjs.PhantomJSDriverService; import org.openqa.selenium.remote.DesiredCapabilities; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.xby1993.common.util.FileUtil; /** * @author taojw */ public class WebDriverPool { private Logger logger = LoggerFactory.getLogger(getClass()); private int CAPACITY = 5; private AtomicInteger refCount = new AtomicInteger(0); private static final String DRIVER_PHANTOMJS = "phantomjs"; /** * store webDrivers available */ private BlockingDeque<WebDriver> innerQueue = new LinkedBlockingDeque<WebDriver>( CAPACITY); private static String PHANTOMJS_PATH; private static DesiredCapabilities caps = DesiredCapabilities.
28
1 min
爬虫框架WebMagic源码分析之Selector 1、Selector部分:
接口:
Selector:定义了根据字符串选择单个元素和选择多个元素的方法。
ElementSelector:定义了根据jsoup element选择单个、多个元素的方法。主要用于CSS、Xpath选择器.
抽象类:
BaseElementSelector,实现类前面说的两个接口,主要用于CSS、Xpath选择器继承。模板化接口方法,并定义了一些选择元素的方法由子类实现。
实现类:
CssSelector:Css选择器的实现类,继承BaseElementSelector。基本实现都是基于jsoup的css选择接口。
XpathSelector:xpath选择器的实现类,继承BaseElementSelector。基本实现都是采用作者自己基于jsoup实现的xsoup的相关接口。
RegexSelector:正则表达式选择器的实现类,仅实现了Selector接口。
JsonPathSelector:基于jayway/JsonPath path选择器。
ReplaceSelector:基于正则替换的选择器
SmartContentSelector:咱不明白其用途,被官方打上了实验性标记。
OrSelector:多个选择的情形,每个选择器各自独立选择,将所有结果合并。
AndSelector:多个选择的情形,流式管道选择,前一个选择的结果作为后一个选择的输入。
2、Selectable部分
接口:Selectable :定义了一系列链式api调用方式,支持xpath,css,regex,jsonPath选择器,以及一些便利方法,如links获取该选择器下的全部链接。
抽象类:AbstractSelectable,定义了一些模板方法。
实现类HtmlNode、PlainText、Html(继承自HtmlNode)、Json(继承自PlainText)等。
这部分源码就不做分析了。
这里需要提到的一点是:
Page.getHtml()返回的Html不支持JsonPath选择,Page.getJson()返回的Json对象支持JsonPath选择。
选择器部分到此结束吧。
下篇主题待定。
806
4 mins
爬虫框架WebMagic源码分析之Downloader Downloader是负责请求url获取返回值(html、json、jsonp等)的一个组件。当然会同时处理POST重定向、Https验证、ip代理、判断失败重试等。
接口:Downloader 定义了download方法返回Page,定义了setThread方法来请求的设置线程数。
抽象类:AbstractDownloader。 定义了重载的download方法返回Html,同时定义了onSuccess、onError状态方法,并定义了addToCycleRetry来判断是否需要进行重试。
实现类:HttpClientDownloader。负责通过HttpClient下载页面
辅助类:HttpClientGenerator。负责生成HttpClient实例。
1、AbstractDownloader
public Html download(String url, String charset) { Page page = download(new Request(url), Site.me().setCharset(charset).toTask()); return (Html) page.getHtml(); } 这里download逻辑很简单,就是调用子类实现的download下载。
protected Page addToCycleRetry(Request request, Site site) { Page page = new Page(); Object cycleTriedTimesObject = request.