基于 asyncio 的异步爬虫框架,有兴趣来看看

2018-09-10 08:49:15 +08:00
 xiaozizayang

轻量异步爬虫框架 aspider ,基于 asyncio

介绍

对于单页面,只要实现框架定义的 Item 就好:

import asyncio

from aspider import AttrField, TextField, Item


class HackerNewsItem(Item):
    target_item = TextField(css_select='tr.athing')
    title = TextField(css_select='a.storylink')
    url = AttrField(css_select='a.storylink', attr='href')

    async def clean_title(self, value):
        return value


items = asyncio.get_event_loop().run_until_complete(HackerNewsItem.get_items(url="https://news.ycombinator.com/"))
for item in items:
    print(item.title, item.url)

Notorious ‘ Hijack Factory ’ Shunned from Web https://krebsonsecurity.com/2018/07/notorious-hijack-factory-shunned-from-web/
 ......

对于多页面的网站,使用 Spider 即可:

import aiofiles

from aspider import AttrField, TextField, Item, Spider


class HackerNewsItem(Item):
    target_item = TextField(css_select='tr.athing')
    title = TextField(css_select='a.storylink')
    url = AttrField(css_select='a.storylink', attr='href')

    async def clean_title(self, value):
        return value


class HackerNewsSpider(Spider):
    start_urls = ['https://news.ycombinator.com/', 'https://news.ycombinator.com/news?p=2']

    async def parse(self, res):
        items = await HackerNewsItem.get_items(html=res.html)
        for item in items:
            async with aiofiles.open('./hacker_news.txt', 'a') as f:
                await f.write(item.title + '\n')


if __name__ == '__main__':
    HackerNewsSpider.start()
[2018-07-11 17:50:12,430]-aspider-INFO  Spider started!
[2018-07-11 17:50:12,430]-Request-INFO  <GET: https://news.ycombinator.com/>
[2018-07-11 17:50:12,456]-Request-INFO  <GET: https://news.ycombinator.com/news?p=2>
[2018-07-11 17:50:14,785]-aspider-INFO  Time usage: 0:00:02.355062
[2018-07-11 17:50:14,785]-aspider-INFO  Spider finished!

同样支持 js 加载:

request = Request("https://www.jianshu.com/", load_js=True)
response = asyncio.get_event_loop().run_until_complete(request.fetch())
print(response.body)

在 Item 以及 Spider 中要是想加载 js,同样只要带上 load_js=True 即可

项目 Github 地址:aspider

5493 次点击
所在节点    Python
32 条回复
xiaozizayang
2018-09-12 08:16:55 +08:00
@hwywhywl 如果可以的话麻烦提个 issue
hwywhywl
2018-09-12 19:11:44 +08:00
@xiaozizayang 已提
xiaozizayang
2018-09-12 22:30:39 +08:00
@hwywhywl 修复了
sugarguo
2018-09-18 11:45:45 +08:00
我又来了,先回复一个再定位

可能是个 bug:
start_urls 如果有不能匹配规则的链接,后面的所有连接全部报错
例如:
http://www.example.com/article/123.html
http://www.example.com/article/123.html
http://www.example.com/article/123.html
http://www.example.com/article/123.html
sugarguo
2018-09-18 11:48:10 +08:00
emmm...还没打完就发出去了

例如
http://域名 /article/123.html
http://域名 /article/124.html
http://域名 /
http://域名 /article/126.html
http://域名 /article/127.html

这样的 urls,第三个没有获取,会导致最后两个报错
我再定位下
xiaozizayang
2018-09-18 13:57:35 +08:00
@sugarguo 你好,感谢你提的 bug,不过我不大明白你的意思,可以整理下再结合具体代码提哥 issue 么?
lixuda
2018-10-06 21:47:15 +08:00
pyppeteer 安装是不是很麻烦?必须 fq ? win10 下
xiaozizayang
2018-10-07 11:20:23 +08:00
@lixuda 我这边安装还好,或者你可以手动安装,然后你可以关注下我正在为 aspider 编写的 splash 插件,也可以方便的加载 js https://github.com/aspider-plugins/aspider-splash
lixuda
2018-10-07 13:11:43 +08:00
@xiaozizayang 我用 http://npm.taobao.org/mirrors 镜像下载。好的,你的框架不错,试用中
xiaozizayang
2018-10-07 21:08:57 +08:00
@lixuda 好的 欢迎提意见
lixuda
2018-10-08 10:35:21 +08:00
@xiaozizayang request = Request("http://www.lutec.com/", load_js=True),直接 timeout,无法退出,是否要设置什么参数
xiaozizayang
2018-10-08 11:10:28 +08:00
@lixuda 你直接 通过里面的二维码进交流群吧 来讨论下你的问题 https://github.com/howie6879/aspider/blob/master/docs/cn/README.md

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/487739

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX