1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 # asyncio爬虫、去重、入库 4 5 import asyncio 6 import re 7 8 import aiohttp 9 import aiomysql 10 from pyquery import PyQuery 11 from aiohttp import TCPConnector 12 13 14 start_url = 'http://www.xbiquge.la/paihangbang/' 15 waitting_urls = [] 16 seen_urls = set() 17 stopping = False 18 19 sem = asyncio.Semaphore(3) 20 21 22 async def fetch(url, session): 23 async with sem: 24 try: 25 async with session.get(url) as resp: 26 print('url status: {}'.format(resp.status)) 27 if resp.status in [200, 201]: 28 data = await resp.text() 29 return data 30 except Exception as e: 31 print(e) 32 33 34 def extract_urls(html): 35 pq = PyQuery(html) 36 for link in pq.items('a'): 37 url = link.attr('href') 38 if url and url.startswith('http') and url not in seen_urls: 39 global waitting_urls 40 waitting_urls.append(url) 41 42 43 async def init_urls(url, session): 44 html = await fetch(url, session) 45 seen_urls.add(url) 46 extract_urls(html) 47 48 49 async def article_handle(url, session, pool): 50 # 获取文章详情并解析入库 51 html = await fetch(url, session) 52 seen_urls.add(url) 53 extract_urls(html) 54 pq = PyQuery(html) 55 title = pq("title").text() 56 # title = title + ' ' 57 async with pool.acquire() as conn: 58 async with conn.cursor() as cur: 59 insert_sql = "INSERT INTO article_test VALUES('{}')".format(title) 60 print(insert_sql) 61 await cur.execute(insert_sql) 62 # 文件操作 63 # with open('aiohttp_spider.txt', mode='a', encoding='utf-8') as file_object: 64 # file_object.write(title) 65 66 67 async def consumer(pool, session): 68 while not stopping: 69 if len(waitting_urls) == 0: 70 await asyncio.sleep(0.5) 71 continue 72 73 url = waitting_urls.pop() 74 print('start get url: {}'.format(url)) 75 if re.match('http://www.xbiquge.la/d+/d+/', url): 76 if url not in seen_urls: 77 asyncio.ensure_future(article_handle(url, session, pool)) 78 else: 79 if url not in seen_urls: 80 asyncio.ensure_future(init_urls(url, session)) 81 82 83 async def main(loop): 84 # 等待mysql连接建立好 85 pool = await aiomysql.create_pool(host='127.0.0.1', port=3306, 86 user='root', password='123456', 87 db='aiomysql_test', loop=loop, 88 charset='utf8', autocommit=True) 89 90 session = aiohttp.ClientSession() 91 html = await fetch(start_url, session) 92 seen_urls.add(start_url) 93 extract_urls(html) 94 95 asyncio.ensure_future(consumer(pool, session)) 96 97 98 if __name__ == '__main__': 99 loop = asyncio.get_event_loop() 100 asyncio.ensure_future(main(loop)) 101 loop.run_forever()