前言
需要使用的模块beautifulsoup,然后结合mongodb来存放数据
使用beautifulsoup来爬取网页信息原理
我们可以通过审核元素来copy目标的路径信息,比较常用的有css selector和xpath(xpath被誉为神器,也比较容易理解,但是先学习beautifulsoup),但是beautifulsoup只认识css selector.所以我们通过复制目标的css selector来做到爬取它的目标
关于xpath和css selector
xpath : 谁,在哪,第几个
css selector : 谁,在哪,第几个,长什么样子
beautifulsoup使用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| * 导入所需要的库 from bs4 import BeautifulSoup import requests * 指定Url url = "" * 使用request来获取网页内容 data = requests.get(url) * 使用beautifulsoup来解析网页 soup = BeautifulSoup(data.text,'lxml') * 使用浏览器的审核元素,copy想要爬去元素的css selector titles = soup.select('xxxxxx') tags = soup.select('') imgs = soup.select('img[width="30"]') **** 注意: ---文章的标签通常是多对一结构,要获得一个信息的所有标签,就要在标签的父级目录停下来 ---可以在select中添加目标的特殊信息,例如soup.select('img[width="30"]')筛选出img标签中宽为10的图片。 **** * 筛选信息,将他们装在一个字典中 for title,tag,img in zip(titles,tags,imgs): data = { 'title':title.get_text(), 'tag':list(tag.stripped_strings) 如果用get_text只会获取其中的一个,stripped_strings算是get_text的升级版本,获取一个父级标签下所有子标签的正文 'img':img.get('src') get是获取标签的属性值,对于图片,我们通常爬取的是他的链接 } print(data)
|
如果要对他进行优化,比如我想筛选出评分大于3的文章
1 2 3 4 5 6
| info = [] info.append(data) for i in info: if i['cate']>3: print(i['title']) ....
|
小技巧,比如爬取图片地址,有些地址是在js文件中,所以爬取很麻烦,我们可以通过chrome浏览器中的模拟手机功能来利用相同的方法来抓取,因为手机端不会加载过多的js文件,这样一来爬取图片链接也简单了许多。
注意:使用request记得在里边添加headers,让服务器知道你是手机端而不是电脑。
mongodb使用方法
对于下载和使用mongodb可以参考MongoDB 教程
还有pycharm中mongo插件的使用,以及下载安装与mongodb做连接的pymongo库…
对于代码中mongodb的创建,我们可以把他和execl来联系起来。我们先要给一个表名称,而这个表的主体内容还可以分为sheet1,sheet2….
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| * 导入可以与mongodb连接的库文件,当然前提你要安装Mongodb import pymongo * 激活mongodb,因为我们是部署在本地中,所以创建在本地 client = pymongo.MongoClient('localhost',27017) * 给execl一个标题 execl0 = client('execl0') 左边的是Python对象,右边的是mongodb中数据库名称,建议一致 * 给execl一个sheet sheet1 = execl0['sheet1'] 在execl0中创建一个sheet * 此处从beautifulsoup那里连接开始 sheet1.insert_one(data) 这个是在表execl0中的sheet1中插入数据 * 使用find来找出数据,find后边可以添加条件,条件要为字典格式。使用以下指令来进行筛选,$lt/$lte/$gt/$gte/$ne依次等价于 <、<=、>、>=、!=。 *格式 sheet1.find({'评分':$lt3}) for item in sheet1.find(): print item
|
实战-开始爬取58同城数据
first.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| from bs4 import BeautifulSoup import requests
url = 'http://jq.58.com/sale.shtml' url_host = 'http://jq.58.com/' def get_info(url): web_data = requests.get(url) soup = BeautifulSoup(web_data.text,'lxml') links = soup.select('ul.ym-submnu > li > b > a') for i in links: page = url_host + i.get('href') print(page) chew_link = ''' http://jq.58.com//shouji/ http://jq.58.com//shoujihao/ http://jq.58.com//tongxunyw/ http://jq.58.com//danche/ http://jq.58.com//fzixingche/ http://jq.58.com//diandongche/ http://jq.58.com//sanlunche/ http://jq.58.com//peijianzhuangbei/ http://jq.58.com//diannao/ http://jq.58.com//bijiben/ http://jq.58.com//pbdn/ http://jq.58.com//diannaopeijian/ http://jq.58.com//zhoubianshebei/ http://jq.58.com//shuma/ http://jq.58.com//shumaxiangji/ http://jq.58.com//mpsanmpsi/ http://jq.58.com//youxiji/ http://jq.58.com//jiadian/ http://jq.58.com//dianshiji/ http://jq.58.com//ershoukongtiao/ http://jq.58.com//xiyiji/ http://jq.58.com//bingxiang/ http://jq.58.com//binggui/ http://jq.58.com//chuang/ http://jq.58.com//ershoujiaju/ http://jq.58.com//bangongshebei/ http://jq.58.com//diannaohaocai/ http://jq.58.com//bangongjiaju/ http://jq.58.com//ershoushebei/ http://jq.58.com//yingyou/ http://jq.58.com//yingeryongpin/ http://jq.58.com//muyingweiyang/ http://jq.58.com//muyingtongchuang/ http://jq.58.com//yunfuyongpin/ http://jq.58.com//fushi/ http://jq.58.com//nanzhuang/ http://jq.58.com//fsxiemao/ http://jq.58.com//xiangbao/ http://jq.58.com//meirong/ http://jq.58.com//yishu/ http://jq.58.com//shufahuihua/ http://jq.58.com//zhubaoshipin/ http://jq.58.com//yuqi/ http://jq.58.com//tushu/ http://jq.58.com//tushubook/ http://jq.58.com//wenti/ http://jq.58.com//yundongfushi/ http://jq.58.com//jianshenqixie/ http://jq.58.com//huju/ http://jq.58.com//qiulei/ http://jq.58.com//yueqi/ http://jq.58.com//chengren/ http://jq.58.com//nvyongpin/ http://jq.58.com//qinglvqingqu/ http://jq.58.com//qingquneiyi/ http://jq.58.com//chengren/ http://jq.58.com//xiaoyuan/ http://jq.58.com//ershouqiugou/ http://jq.58.com//tiaozao/ http://jq.58.com//tiaozao/ http://jq.58.com//tiaozao/
'''
|
second.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| from bs4 import BeautifulSoup import pymongo import requests
client = pymongo.MongoClient('localhost',27017) walden = client['walden'] sheet = walden['sheet'] info = walden['info']
def get_link(url,page,who_sell=0): chew_list = '{}{}/pn{}'.format(url,str(who_sell),str(page)) web_data = requests.get(chew_list) soup = BeautifulSoup(web_data.text,'lxml') src = soup.select(' div.infocon > table > tbody > tr.zzinfo > td.t > a') for links in src: a = links.get('href').split('?')[0] sheet.insert_one({'link':a}) print(a)
def get_info(url): web_data = requests.get(url) soup = BeautifulSoup(web_data.text,'lxml') title = soup.title.text price = soup.select('div.info_lubotu.clearfix > div.info_massege.left > div.price_li > span')[0].text area = soup.select('div.info_lubotu.clearfix > div.info_massege.left > div.palce_li > span')[0].text info.insert_one({ 'title':title, 'price':price, 'area':area })
|
third.py
1 2 3 4 5 6 7 8 9 10 11
| from multiprocessing import Pool from first import chew_link from second import get_link
def total_link(url): for num in range(1,101): get_link(url,num)
if __name__ == '__main__': pool = Pool() pool.map(total_link,chew_link.split())
|
fourth,py
1 2 3 4 5
| import time from second import sheet while True: print(sheet.find().count()) time.sleep(3)
|
以上就是python+mongodb+beautifulsoup+多进程 来爬取十万级数据的方法,但是比较懒,还有好多优化的地方以变得更加方便以及更少的代码,但是没有进行优化…这是一大不足
fourth.py实现了一个数据库计数的功能。third.py结合first.py,second.py的方法,在结合多进程来来实现。
second.py是爬取通过first传递过来的所需要的信息。运行时运行fourth和third就可以了。
QQ:709516041 如有不懂的可以来问我,也欢迎有大神前来指点我的不足
同时也在此感谢俊富给我的资料。