2019-3 九龙坡爬虫
目标:爬取url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002’里面70页所有的1.中标公示的名称 日期,以及每个中标公告的url
2.进入每个url爬取里面的字段
这是每个中标公示里面的内容:我们需要爬取项目名称,招标公告编号,招标人,招标代理机构,招标结果中的三个待定中标者,中标人,以及投诉受理部门。
爬虫步骤:
1.获取每个html界面,并解析每个html界面
2.用xpath定位器取东西
3.将爬取的数据进行存储
爬虫中需要解决的问题:
1.如何获取每个界面,(网页翻页问题)
2.如何正确的取到需要的数据的xpath,(有坑)
3.csv数据格式 存储问题
解决问题:
1.当点击下一页的时候,发现上方的url不变,这就很奇怪了,那怎样让程序自动到下一页呢?
这种:url只有一个,但是可以有很多界面的问题,就需要我们抓包,查看表单数据,通过post请求修改表单数据,从而翻页。
1.先鼠标右击 选 检查,选择上方的network,再选择doc,之后点击一下 下一页,服务器就会发过来下面三个包裹,点击第一个,
fromdata就是表单数据,往下翻会有出现,_EVEENTEVENTARGUMENT:3, (为什么会看表单数据中的这个? 因为每一个下一页,你去看表单数据,你会发现,当是第三页的时候,这个参数是3,当第四页的时候,会是4,所以不同界面,跟这个参数有关。)
第四页的时候,这个参数后面数字是4,多看几个,发现第几页,这个数字就是多少,因此我们只需要修改这个表单数据中的这个参数,就能实现翻页了
实现翻页的代码:(用循环,实现70页的翻页)
import requests
from lxml import etree
for i in range(1,71):
url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
#post请求修改表单数据 只需要写要修改的部分,不需要把表单里的全部内容都写进去
playload={'__EVENTARGUMENT':i}#post请求修改表单数据实现翻页
r=requests.post(url, headers=headers, data=playload,timeout=30)
r.encoding='utf-8'
html=etree.HTML(r.text)#用etree解析界面,从而可以使用xpath定位器
2.xpath的坑,切记不要经常在浏览器上直接复制xpath,虽然直接复制的能在xpath匹配器上匹配得到东西,但是放在代码里,偶尔会错。(因为浏览器上有时会自动规范网页,会出现多余对的标签,主要会出现tbody标签,)。因此每次从浏览器上复制的xpath 出现tbody 就把它删除用//代替
3.注意:csv写入excel的坑:
1.当header(列表)有的时候,要写入的数据infos中字典的键要与header中的值一样
2.infos一定要为列表 ,并且需要当全部数据都装在infos中后,才开始存进本地。
全代码:
import requests
import csv
from bs4 import BeautifulSoup
from lxml import etree
def main():
#global url
#url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
# headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) #Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
#'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
infos=[]
header2=['公告','时间','网址','项目名称','招标公告编号','招标人','招标代理机构','待选者1','待选者2','待选者3','中标人','投诉受理部门']
#post修改表单数据,实现翻页
for i in range(1,71):
url='http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'
headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3626.400 QQBrowser/10.4.3211.400',
'Referer':'http://www.cqjlpggzyzhjy.gov.cn/cqjl/jyxx/003001/003001002/MoreInfo.aspx?CategoryNum=003001002'}
#post请求修改表单数据 只需要写要修改的部分,不需要把表单里的全部内容都写进去
playload={'__VIEWSTATEGENERATOR': '7A07C098','__EVENTTARGET': 'MoreInfoList1$Pager','__EVENTARGUMENT':i}
r=requests.post(url, headers=headers, data=playload,timeout=30)
r.encoding='utf-8' #或者 r.content.decode('utf-8') html=etree.HTML(r)
html=etree.HTML(r.text)
#xpath提取所有tr标签 尾部没有text()
trs = html.xpath("//table[@id]//td[@id='MoreInfoList1_tdcontent']//tr")
for tr in trs:
#取表题,[0]表示取值
name=tr.xpath('.//td[2]/a/text()')[0]
#取日期
time=(tr.xpath('./td[3]/text()')[0]).replace('\n','').replace('\r','')
#拼接url
url="http://www.cqjlpggzyzhjy.gov.cn" + tr.xpath("./td[2]/a/@href")[0]
r2=requests.get(url,headers=headers).text
r.encoding='utf-8'
html2=etree.HTML(r2)
#注意tbody,最好删除,切记不可直接复制浏览器中的xpath,有时会出错。
#每个公告里面需要提取的字段。
a=html2.xpath("//*[@id='TDContent']/div/table//tr[1]/td[2]/p/text()")
b=html2.xpath("//*[@id='TDContent']/div/table//tr[2]/td[2]/p/span/text()")
c=html2.xpath("//*[@id='TDContent']/div/table//tr[3]/td[2]/p//text()")
d=html2.xpath("//*[@id='TDContent']/div/table//tr[4]/td[2]/p/span/text()")
e=html2.xpath("//*[@id='TDContent']/div/table//tr[6]/td[2]/p/span/text()")
f=html2.xpath("//*[@id='TDContent']/div/table//tr[7]/td[2]/p/span/text()")
g=html2.xpath("//*[@id='TDContent']/div/table//tr[8]/td[2]/p/span/text()")
h=html2.xpath("//*[@id='TDContent']/div/table//tr[9]/td[2]/p/span/text()")
i=html2.xpath("//*[@id='TDContent']/div/table//tr[10]/td[2]/p/span/text()")
data={'公告':name,
'时间':time,
'网址':url,
'项目名称':a,
'招标公告编号':b,
'招标人':c,
'招标代理机构':d,
'待选者1':e,
'待选者2':f,
'待选者3':g,
'中标人':h ,
'投诉受理部门':i,}
infos.append(data)
#当数据全部存放在infos中后,保存数据
with open('2019-3 九龙坡.csv','w',encoding='utf-8',newline='') as fp:
writer=csv.DictWriter(fp,header2)
writer.writeheader()
writer.writerows(infos)
main()
文章作者:张川
作者QQ:468336329
备注:本文纯属原创,未经同意请勿转载。