作业要求:
抓取http://www.socom.cn 网站公司信息数据信息。
可以看这个页面,有兴趣的可以抓全站 至少抓一个省的
因为期末考试的原因耽搁了好久,大概有一个月没有写代码,手生了,接下来要继续努力了。
写这个爬虫之前,由于之前用的是2.7,这次决定开始尽量用3.5,其实差别不大。搭建环境什么的又折腾了一下。记录一下搭建环境过程中遇到的问题。
1.Pycharm
默认搭建的虚拟环境pip包没有不是最新的,尽量升级成最新的,这样会后面装别的会少很多坑。
pip
和easy_install
参考:http://blog.csdn.net/xsj_blog/article/details/52037609
2.最新的lxml
包竟然没有etee
模块...
解决参考:http://blog.csdn.net/u012614287/article/details/71177920
下面进入正题
乍一看这个网站,感觉贼复杂,该用什么思路去爬呢?
我决定从大标题入手,不走细分的小标题,我走的思路就是直接从浙江省农、林、牧、渔业,浙江省采矿业,浙江省制造业这样的大标题切入
切入之后,点击下面红字,发现url变了,仔细分析http://www.socom.cn/company/company_list.jsp?categoryId=10&locationId=33&name=&cp=2 categoryId 就是我切入的类目序号,locationId 就是省份序号,cp 是页码
只要获取了所有的这样的url,就能获得所有的企业url。
所有类目url:
for categoryId in range(10, 31):
first_url = "http://www.socom.cn/company/company_list.jsp?categoryId=" + str(categoryId) + \
"&locationId=33&name=&cp=1"
page_nums = int(get_total_page(first_url))
for cp in range(1, page_nums + 1):
category_url = "http://www.socom.cn/company/company_list.jsp?categoryId=" + str(categoryId) + \
"&locationId=33&name=&cp=" + str(cp)
category_urls.append(category_url)
所有企业url:
for url in category_urls:
html = requests.get(url=url, headers=headers).text
selector = etree.HTML(html)
temp_urls = selector.xpath("//div[6]/div/a/@href")
for temp_url in temp_urls:
company_url = "http://www.socom.cn" + temp_url
抓到了企业url,接下来就是抓信息了。抓信息的时候处理上面的地区和企业属性分类的时候特别麻烦。
有些没有区的,有些没有属性的,标准的是3+4形式,也有2+4,3+3,3+1等等的形式,思考了半天,想出一个好方法!直接看代码吧!
Administrative_Region = [
'上城区', '下城区', '江干区', '拱墅区', '西湖区', '滨江区', '萧山区', '余杭区', '桐庐县', '淳安县', '建德市', '富阳区', '临安市',
'海曙区', '江北区', '北仑区', '镇海区', '鄞州区', '奉化区', '象山县', '宁海县', '余姚市', '慈溪市',
'鹿城区', '龙湾区', '瓯海区', '洞头区', '永嘉县', '平阳县', '苍南县', '文成县', '泰顺县', '瑞安市', '乐清市',
'南湖区', '秀洲区', '嘉善县', '海盐县', '海宁市', '平湖市', '桐乡市',
'吴兴区', '南浔区', '德清县', '长兴县', '安吉县',
'越城区', '柯桥区', '新昌县', '诸暨市', '上虞区', '嵊州市',
'婺城区', '金东区', '武义县', '浦江县', '磐安县', '兰溪市', '义乌市', '东阳市', '永康市',
'柯城区', '衢江区', '常山县', '开化县', '龙游县', '江山市',
'椒江区', '黄岩区', '路桥区', '玉环市', '三门县', '天台县', '仙居县', '温岭市', '临海市',
'莲都区', '青田县', '缙云县', '遂昌县', '松阳县', '云和县', '庆元县', '景宁县', '龙泉市'
]
company_descriptions = selector.xpath("//div[2]/div/a[position()>1]/text()")
if company_descriptions[2] in Administrative_Region:
company_address = company_descriptions[0:3]
company_attr = '-'.join(company_descriptions[3:])
else:
company_address = company_descriptions[0:2]
company_address.append('')
company_attr = '-'.join(company_descriptions[2:])
for address in company_address:
company_information.append(address)
company_information.append(company_attr)
用第三个行政区来划分是最好的,这样弄出来的数据一致性就会好很多,接下来处理数据就会方便很多!
好了,其他的就没什么了,关键点已经解决了,放上完整代码。
# -*- coding:utf-8 -*-
import requests
from lxml import etree
headers = {
"User-Agent": "Mozilla / 5.0(Windows NT 6.1;Win64;x64)"
"AppleWebKit / 537.36(KHTML, likeGecko)"
"Chrome / 58.0.3029.110"
"Safari / 537.36"
}
Administrative_Region = [
'上城区', '下城区', '江干区', '拱墅区', '西湖区', '滨江区', '萧山区', '余杭区', '桐庐县', '淳安县', '建德市', '富阳区', '临安市',
'海曙区', '江北区', '北仑区', '镇海区', '鄞州区', '奉化区', '象山县', '宁海县', '余姚市', '慈溪市',
'鹿城区', '龙湾区', '瓯海区', '洞头区', '永嘉县', '平阳县', '苍南县', '文成县', '泰顺县', '瑞安市', '乐清市',
'南湖区', '秀洲区', '嘉善县', '海盐县', '海宁市', '平湖市', '桐乡市',
'吴兴区', '南浔区', '德清县', '长兴县', '安吉县',
'越城区', '柯桥区', '新昌县', '诸暨市', '上虞区', '嵊州市',
'婺城区', '金东区', '武义县', '浦江县', '磐安县', '兰溪市', '义乌市', '东阳市', '永康市',
'柯城区', '衢江区', '常山县', '开化县', '龙游县', '江山市',
'椒江区', '黄岩区', '路桥区', '玉环市', '三门县', '天台县', '仙居县', '温岭市', '临海市',
'莲都区', '青田县', '缙云县', '遂昌县', '松阳县', '云和县', '庆元县', '景宁县', '龙泉市'
]
# def get_first_url():
# html = requests.get(url=start_url, headers=headers).text
# selector = etree.HTML(html)
# first_urls = ["http://www.socom.cn"+str(url) for url in selector.xpath("//div[@class='provinceBox']/a/@href")]
# return first_urls
def get_total_page(first_url):
html = requests.get(url=first_url, headers=headers).text
selector = etree.HTML(html)
page_nums = selector.xpath("//div[@class='description']/table/tr/td[1]/font[2]/text()")[0]
return page_nums
def get_company_url():
category_urls = []
for categoryId in range(10, 31):
first_url = "http://www.socom.cn/company/company_list.jsp?categoryId=" + str(categoryId) + \
"&locationId=33&name=&cp=1"
page_nums = int(get_total_page(first_url))
for cp in range(1, page_nums + 1):
category_url = "http://www.socom.cn/company/company_list.jsp?categoryId=" + str(categoryId) + \
"&locationId=33&name=&cp=" + str(cp)
category_urls.append(category_url)
for url in category_urls:
html = requests.get(url=url, headers=headers).text
selector = etree.HTML(html)
temp_urls = selector.xpath("//div[6]/div/a/@href")
for temp_url in temp_urls:
company_url = "http://www.socom.cn" + temp_url
print(company_url)
get_company_information(company_url)
def get_company_information(company_url):
company_information = []
html = requests.get(url=company_url, headers=headers).text
selector = etree.HTML(html)
company_name = selector.xpath("//div[3]/div[1]/text()")[0]
company_information.append(company_name)
company_descriptions = selector.xpath("//div[2]/div/a[position()>1]/text()")
if company_descriptions[2] in Administrative_Region:
company_address = company_descriptions[0:3]
company_attr = '-'.join(company_descriptions[3:])
else:
company_address = company_descriptions[0:2]
company_address.append('')
company_attr = '-'.join(company_descriptions[2:])
for address in company_address:
company_information.append(address)
company_information.append(company_attr)
company_details = selector.xpath("//div[3]/div[2]/div[1]/text()")
for company_detail in company_details:
company_information.append(str.replace(company_detail, u'\xa0', u'').strip())
print(company_information)
if __name__ == "__main__":
get_company_url()
结果
还算比较整齐的。
写到数据里的部分下次补上,来不及了,先记录一部分。